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

// Copyright (C) 2011-2018 Free Software Foundation, Inc.
// Written by Sasa Stankovic <sasa.stankovic@imgtec.com>
//        and Aleksandar Simeonov <aleksandar.simeonov@rt-rk.com>.
// This file contains borrowed and adapted code from bfd/elfxx-mips.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 <algorithm>
#include <set>
#include <sstream>
#include "demangle.h"

#include "elfcpp.h"
#include "parameters.h"
#include "reloc.h"
#include "mips.h"
#include "object.h"
#include "symtab.h"
#include "layout.h"
#include "output.h"
#include "copy-relocs.h"
#include "target.h"
#include "target-reloc.h"
#include "target-select.h"
#include "tls.h"
#include "errors.h"
#include "gc.h"
#include "attributes.h"
#include "nacl.h"

namespace
{
using namespace gold;

template<int size, bool big_endian>
class Mips_output_data_plt;

template<int size, bool big_endian>
class Mips_output_data_got;

template<int size, bool big_endian>
class Target_mips;

template<int size, bool big_endian>
class Mips_output_section_reginfo;

template<int size, bool big_endian>
class Mips_output_section_options;

template<int size, bool big_endian>
class Mips_output_data_la25_stub;

template<int size, bool big_endian>
class Mips_output_data_mips_stubs;

template<int size>
class Mips_symbol;

template<int size, bool big_endian>
class Mips_got_info;

template<int size, bool big_endian>
class Mips_relobj;

class Mips16_stub_section_base;

template<int size, bool big_endian>
class Mips16_stub_section;

// The ABI says that every symbol used by dynamic relocations must have
// a global GOT entry.  Among other things, this provides the dynamic
// linker with a free, directly-indexed cache.  The GOT can therefore
// contain symbols that are not referenced by GOT relocations themselves
// (in other words, it may have symbols that are not referenced by things
// like R_MIPS_GOT16 and R_MIPS_GOT_PAGE).

// GOT relocations are less likely to overflow if we put the associated
// GOT entries towards the beginning.  We therefore divide the global
// GOT entries into two areas: "normal" and "reloc-only".  Entries in
// the first area can be used for both dynamic relocations and GP-relative
// accesses, while those in the "reloc-only" area are for dynamic
// relocations only.

// These GGA_* ("Global GOT Area") values are organised so that lower
// values are more general than higher values.  Also, non-GGA_NONE
// values are ordered by the position of the area in the GOT.

enum Global_got_area
{
  GGA_NORMAL = 0,
  GGA_RELOC_ONLY = 1,
  GGA_NONE = 2
};

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

  // GOT entries for multi-GOT. We support up to 1024 GOTs in multi-GOT links.
  GOT_TYPE_STANDARD_MULTIGOT = 3,
  GOT_TYPE_TLS_OFFSET_MULTIGOT = GOT_TYPE_STANDARD_MULTIGOT + 1024,
  GOT_TYPE_TLS_PAIR_MULTIGOT = GOT_TYPE_TLS_OFFSET_MULTIGOT + 1024
};

// TLS type of GOT entry.
enum Got_tls_type
{
  GOT_TLS_NONE = 0,
  GOT_TLS_GD = 1,
  GOT_TLS_LDM = 2,
  GOT_TLS_IE = 4
};

// Values found in the r_ssym field of a relocation entry.
enum Special_relocation_symbol
{
  RSS_UNDEF = 0,    // None - value is zero.
  RSS_GP = 1,       // Value of GP.
  RSS_GP0 = 2,      // Value of GP in object being relocated.
  RSS_LOC = 3       // Address of location being relocated.
};

// Whether the section is readonly.
static inline bool
is_readonly_section(Output_section* output_section)
{
  elfcpp::Elf_Xword section_flags = output_section->flags();
  elfcpp::Elf_Word section_type = output_section->type();

  if (section_type == elfcpp::SHT_NOBITS)
    return false;

  if (section_flags & elfcpp::SHF_WRITE)
    return false;

  return true;
}

// Return TRUE if a relocation of type R_TYPE from OBJECT might
// require an la25 stub.  See also local_pic_function, which determines
// whether the destination function ever requires a stub.
template<int size, bool big_endian>
static inline bool
relocation_needs_la25_stub(Mips_relobj<size, big_endian>* object,
                           unsigned int r_type, bool target_is_16_bit_code)
{
  // We specifically ignore branches and jumps from EF_PIC objects,
  // where the onus is on the compiler or programmer to perform any
  // necessary initialization of $25.  Sometimes such initialization
  // is unnecessary; for example, -mno-shared functions do not use
  // the incoming value of $25, and may therefore be called directly.
  if (object->is_pic())
    return false;

  switch (r_type)
    {
    case elfcpp::R_MIPS_26:
    case elfcpp::R_MIPS_PC16:
    case elfcpp::R_MIPS_PC21_S2:
    case elfcpp::R_MIPS_PC26_S2:
    case elfcpp::R_MICROMIPS_26_S1:
    case elfcpp::R_MICROMIPS_PC7_S1:
    case elfcpp::R_MICROMIPS_PC10_S1:
    case elfcpp::R_MICROMIPS_PC16_S1:
    case elfcpp::R_MICROMIPS_PC23_S2:
      return true;

    case elfcpp::R_MIPS16_26:
      return !target_is_16_bit_code;

    default:
      return false;
    }
}

// Return true if SYM is a locally-defined PIC function, in the sense
// that it or its fn_stub might need $25 to be valid on entry.
// Note that MIPS16 functions set up $gp using PC-relative instructions,
// so they themselves never need $25 to be valid.  Only non-MIPS16
// entry points are of interest here.
template<int size, bool big_endian>
static inline bool
local_pic_function(Mips_symbol<size>* sym)
{
  bool def_regular = (sym->source() == Symbol::FROM_OBJECT
                      && !sym->object()->is_dynamic()
                      && !sym->is_undefined());

  if (sym->is_defined() && def_regular)
    {
      Mips_relobj<size, big_endian>* object =
        static_cast<Mips_relobj<size, big_endian>*>(sym->object());

      if ((object->is_pic() || sym->is_pic())
          && (!sym->is_mips16()
              || (sym->has_mips16_fn_stub() && sym->need_fn_stub())))
        return true;
    }
  return false;
}

static inline bool
hi16_reloc(int r_type)
{
  return (r_type == elfcpp::R_MIPS_HI16
          || r_type == elfcpp::R_MIPS16_HI16
          || r_type == elfcpp::R_MICROMIPS_HI16
          || r_type == elfcpp::R_MIPS_PCHI16);
}

static inline bool
lo16_reloc(int r_type)
{
  return (r_type == elfcpp::R_MIPS_LO16
          || r_type == elfcpp::R_MIPS16_LO16
          || r_type == elfcpp::R_MICROMIPS_LO16
          || r_type == elfcpp::R_MIPS_PCLO16);
}

static inline bool
got16_reloc(unsigned int r_type)
{
  return (r_type == elfcpp::R_MIPS_GOT16
          || r_type == elfcpp::R_MIPS16_GOT16
          || r_type == elfcpp::R_MICROMIPS_GOT16);
}

static inline bool
call_lo16_reloc(unsigned int r_type)
{
  return (r_type == elfcpp::R_MIPS_CALL_LO16
          || r_type == elfcpp::R_MICROMIPS_CALL_LO16);
}

static inline bool
got_lo16_reloc(unsigned int r_type)
{
  return (r_type == elfcpp::R_MIPS_GOT_LO16
          || r_type == elfcpp::R_MICROMIPS_GOT_LO16);
}

static inline bool
eh_reloc(unsigned int r_type)
{
  return (r_type == elfcpp::R_MIPS_EH);
}

static inline bool
got_disp_reloc(unsigned int r_type)
{
  return (r_type == elfcpp::R_MIPS_GOT_DISP
          || r_type == elfcpp::R_MICROMIPS_GOT_DISP);
}

static inline bool
got_page_reloc(unsigned int r_type)
{
  return (r_type == elfcpp::R_MIPS_GOT_PAGE
          || r_type == elfcpp::R_MICROMIPS_GOT_PAGE);
}

static inline bool
tls_gd_reloc(unsigned int r_type)
{
  return (r_type == elfcpp::R_MIPS_TLS_GD
          || r_type == elfcpp::R_MIPS16_TLS_GD
          || r_type == elfcpp::R_MICROMIPS_TLS_GD);
}

static inline bool
tls_gottprel_reloc(unsigned int r_type)
{
  return (r_type == elfcpp::R_MIPS_TLS_GOTTPREL
          || r_type == elfcpp::R_MIPS16_TLS_GOTTPREL
          || r_type == elfcpp::R_MICROMIPS_TLS_GOTTPREL);
}

static inline bool
tls_ldm_reloc(unsigned int r_type)
{
  return (r_type == elfcpp::R_MIPS_TLS_LDM
          || r_type == elfcpp::R_MIPS16_TLS_LDM
          || r_type == elfcpp::R_MICROMIPS_TLS_LDM);
}

static inline bool
mips16_call_reloc(unsigned int r_type)
{
  return (r_type == elfcpp::R_MIPS16_26
          || r_type == elfcpp::R_MIPS16_CALL16);
}

static inline bool
jal_reloc(unsigned int r_type)
{
  return (r_type == elfcpp::R_MIPS_26
          || r_type == elfcpp::R_MIPS16_26
          || r_type == elfcpp::R_MICROMIPS_26_S1);
}

static inline bool
micromips_branch_reloc(unsigned int r_type)
{
  return (r_type == elfcpp::R_MICROMIPS_26_S1
          || r_type == elfcpp::R_MICROMIPS_PC16_S1
          || r_type == elfcpp::R_MICROMIPS_PC10_S1
          || r_type == elfcpp::R_MICROMIPS_PC7_S1);
}

// Check if R_TYPE is a MIPS16 reloc.
static inline bool
mips16_reloc(unsigned int r_type)
{
  switch (r_type)
    {
    case elfcpp::R_MIPS16_26:
    case elfcpp::R_MIPS16_GPREL:
    case elfcpp::R_MIPS16_GOT16:
    case elfcpp::R_MIPS16_CALL16:
    case elfcpp::R_MIPS16_HI16:
    case elfcpp::R_MIPS16_LO16:
    case elfcpp::R_MIPS16_TLS_GD:
    case elfcpp::R_MIPS16_TLS_LDM:
    case elfcpp::R_MIPS16_TLS_DTPREL_HI16:
    case elfcpp::R_MIPS16_TLS_DTPREL_LO16:
    case elfcpp::R_MIPS16_TLS_GOTTPREL:
    case elfcpp::R_MIPS16_TLS_TPREL_HI16:
    case elfcpp::R_MIPS16_TLS_TPREL_LO16:
      return true;

    default:
      return false;
    }
}

// Check if R_TYPE is a microMIPS reloc.
static inline bool
micromips_reloc(unsigned int r_type)
{
  switch (r_type)
    {
    case elfcpp::R_MICROMIPS_26_S1:
    case elfcpp::R_MICROMIPS_HI16:
    case elfcpp::R_MICROMIPS_LO16:
    case elfcpp::R_MICROMIPS_GPREL16:
    case elfcpp::R_MICROMIPS_LITERAL:
    case elfcpp::R_MICROMIPS_GOT16:
    case elfcpp::R_MICROMIPS_PC7_S1:
    case elfcpp::R_MICROMIPS_PC10_S1:
    case elfcpp::R_MICROMIPS_PC16_S1:
    case elfcpp::R_MICROMIPS_CALL16:
    case elfcpp::R_MICROMIPS_GOT_DISP:
    case elfcpp::R_MICROMIPS_GOT_PAGE:
    case elfcpp::R_MICROMIPS_GOT_OFST:
    case elfcpp::R_MICROMIPS_GOT_HI16:
    case elfcpp::R_MICROMIPS_GOT_LO16:
    case elfcpp::R_MICROMIPS_SUB:
    case elfcpp::R_MICROMIPS_HIGHER:
    case elfcpp::R_MICROMIPS_HIGHEST:
    case elfcpp::R_MICROMIPS_CALL_HI16:
    case elfcpp::R_MICROMIPS_CALL_LO16:
    case elfcpp::R_MICROMIPS_SCN_DISP:
    case elfcpp::R_MICROMIPS_JALR:
    case elfcpp::R_MICROMIPS_HI0_LO16:
    case elfcpp::R_MICROMIPS_TLS_GD:
    case elfcpp::R_MICROMIPS_TLS_LDM:
    case elfcpp::R_MICROMIPS_TLS_DTPREL_HI16:
    case elfcpp::R_MICROMIPS_TLS_DTPREL_LO16:
    case elfcpp::R_MICROMIPS_TLS_GOTTPREL:
    case elfcpp::R_MICROMIPS_TLS_TPREL_HI16:
    case elfcpp::R_MICROMIPS_TLS_TPREL_LO16:
    case elfcpp::R_MICROMIPS_GPREL7_S2:
    case elfcpp::R_MICROMIPS_PC23_S2:
      return true;

    default:
      return false;
    }
}

static inline bool
is_matching_lo16_reloc(unsigned int high_reloc, unsigned int lo16_reloc)
{
  switch (high_reloc)
    {
    case elfcpp::R_MIPS_HI16:
    case elfcpp::R_MIPS_GOT16:
      return lo16_reloc == elfcpp::R_MIPS_LO16;
    case elfcpp::R_MIPS_PCHI16:
      return lo16_reloc == elfcpp::R_MIPS_PCLO16;
    case elfcpp::R_MIPS16_HI16:
    case elfcpp::R_MIPS16_GOT16:
      return lo16_reloc == elfcpp::R_MIPS16_LO16;
    case elfcpp::R_MICROMIPS_HI16:
    case elfcpp::R_MICROMIPS_GOT16:
      return lo16_reloc == elfcpp::R_MICROMIPS_LO16;
    default:
      return false;
    }
}

// This class is used to hold information about one GOT entry.
// There are three types of entry:
//
//    (1) a SYMBOL + OFFSET address, where SYMBOL is local to an input object
//          (object != NULL, symndx >= 0, tls_type != GOT_TLS_LDM)
//    (2) a SYMBOL address, where SYMBOL is not local to an input object
//          (sym != NULL, symndx == -1)
//    (3) a TLS LDM slot (there's only one of these per GOT.)
//          (object != NULL, symndx == 0, tls_type == GOT_TLS_LDM)

template<int size, bool big_endian>
class Mips_got_entry
{
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address;

 public:
  Mips_got_entry(Mips_relobj<size, big_endian>* object, unsigned int symndx,
                 Mips_address addend, unsigned char tls_type,
                 unsigned int shndx, bool is_section_symbol)
    : addend_(addend), symndx_(symndx), tls_type_(tls_type),
      is_section_symbol_(is_section_symbol), shndx_(shndx)
  { this->d.object = object; }

  Mips_got_entry(Mips_symbol<size>* sym, unsigned char tls_type)
    : addend_(0), symndx_(-1U), tls_type_(tls_type),
      is_section_symbol_(false), shndx_(-1U)
  { this->d.sym = sym; }

  // Return whether this entry is for a local symbol.
  bool
  is_for_local_symbol() const
  { return this->symndx_ != -1U; }

  // Return whether this entry is for a global symbol.
  bool
  is_for_global_symbol() const
  { return this->symndx_ == -1U; }

  // Return the hash of this entry.
  size_t
  hash() const
  {
    if (this->tls_type_ == GOT_TLS_LDM)
      return this->symndx_ + (1 << 18);

    size_t name_hash_value = gold::string_hash<char>(
        (this->symndx_ != -1U)
         ? this->d.object->name().c_str()
         : this->d.sym->name());
    size_t addend = this->addend_;
    return name_hash_value ^ this->symndx_ ^ (addend << 16);
  }

  // Return whether this entry is equal to OTHER.
  bool
  equals(Mips_got_entry<size, big_endian>* other) const
  {
    if (this->symndx_ != other->symndx_
        || this->tls_type_ != other->tls_type_)
      return false;

    if (this->tls_type_ == GOT_TLS_LDM)
      return true;

    return (((this->symndx_ != -1U)
              ? (this->d.object == other->d.object)
              : (this->d.sym == other->d.sym))
            && (this->addend_ == other->addend_));
  }

  // Return input object that needs this GOT entry.
  Mips_relobj<size, big_endian>*
  object() const
  {
    gold_assert(this->symndx_ != -1U);
    return this->d.object;
  }

  // Return local symbol index for local GOT entries.
  unsigned int
  symndx() const
  {
    gold_assert(this->symndx_ != -1U);
    return this->symndx_;
  }

  // Return the relocation addend for local GOT entries.
  Mips_address
  addend() const
  { return this->addend_; }

  // Return global symbol for global GOT entries.
  Mips_symbol<size>*
  sym() const
  {
    gold_assert(this->symndx_ == -1U);
    return this->d.sym;
  }

  // Return whether this is a TLS GOT entry.
  bool
  is_tls_entry() const
  { return this->tls_type_ != GOT_TLS_NONE; }

  // Return TLS type of this GOT entry.
  unsigned char
  tls_type() const
  { return this->tls_type_; }

  // Return section index of the local symbol for local GOT entries.
  unsigned int
  shndx() const
  { return this->shndx_; }

  // Return whether this is a STT_SECTION symbol.
  bool
  is_section_symbol() const
  { return this->is_section_symbol_; }

 private:
  // The addend.
  Mips_address addend_;

  // The index of the symbol if we have a local symbol; -1 otherwise.
  unsigned int symndx_;

  union
  {
    // The input object for local symbols that needs the GOT entry.
    Mips_relobj<size, big_endian>* object;
    // If symndx == -1, the global symbol corresponding to this GOT entry.  The
    // symbol's entry is in the local area if mips_sym->global_got_area is
    // GGA_NONE, otherwise it is in the global area.
    Mips_symbol<size>* sym;
  } d;

  // The TLS type of this GOT entry.  An LDM GOT entry will be a local
  // symbol entry with r_symndx == 0.
  unsigned char tls_type_;

  // Whether this is a STT_SECTION symbol.
  bool is_section_symbol_;

  // For local GOT entries, section index of the local symbol.
  unsigned int shndx_;
};

// Hash for Mips_got_entry.

template<int size, bool big_endian>
class Mips_got_entry_hash
{
 public:
  size_t
  operator()(Mips_got_entry<size, big_endian>* entry) const
  { return entry->hash(); }
};

// Equality for Mips_got_entry.

template<int size, bool big_endian>
class Mips_got_entry_eq
{
 public:
  bool
  operator()(Mips_got_entry<size, big_endian>* e1,
             Mips_got_entry<size, big_endian>* e2) const
  { return e1->equals(e2); }
};

// Hash for Mips_symbol.

template<int size>
class Mips_symbol_hash
{
 public:
  size_t
  operator()(Mips_symbol<size>* sym) const
  { return sym->hash(); }
};

// Got_page_range.  This class describes a range of addends: [MIN_ADDEND,
// MAX_ADDEND].  The instances form a non-overlapping list that is sorted by
// increasing MIN_ADDEND.

struct Got_page_range
{
  Got_page_range()
    : next(NULL), min_addend(0), max_addend(0)
  { }

  Got_page_range* next;
  int min_addend;
  int max_addend;

  // Return the maximum number of GOT page entries required.
  int
  get_max_pages()
  { return (this->max_addend - this->min_addend + 0x1ffff) >> 16; }
};

// Got_page_entry.  This class describes the range of addends that are applied
// to page relocations against a given symbol.

struct Got_page_entry
{
  Got_page_entry()
    : object(NULL), symndx(-1U), ranges(NULL), num_pages(0)
  { }

  Got_page_entry(Object* object_, unsigned int symndx_)
    : object(object_), symndx(symndx_), ranges(NULL), num_pages(0)
  { }

  // The input object that needs the GOT page entry.
  Object* object;
  // The index of the symbol, as stored in the relocation r_info.
  unsigned int symndx;
  // The ranges for this page entry.
  Got_page_range* ranges;
  // The maximum number of page entries needed for RANGES.
  unsigned int num_pages;
};

// Hash for Got_page_entry.

struct Got_page_entry_hash
{
  size_t
  operator()(Got_page_entry* entry) const
  { return reinterpret_cast<uintptr_t>(entry->object) + entry->symndx; }
};

// Equality for Got_page_entry.

struct Got_page_entry_eq
{
  bool
  operator()(Got_page_entry* entry1, Got_page_entry* entry2) const
  {
    return entry1->object == entry2->object && entry1->symndx == entry2->symndx;
  }
};

// This class is used to hold .got information when linking.

template<int size, bool big_endian>
class Mips_got_info
{
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address;
  typedef Output_data_reloc<elfcpp::SHT_REL, true, size, big_endian>
    Reloc_section;
  typedef Unordered_map<unsigned int, unsigned int> Got_page_offsets;

  // Unordered set of GOT entries.
  typedef Unordered_set<Mips_got_entry<size, big_endian>*,
      Mips_got_entry_hash<size, big_endian>,
      Mips_got_entry_eq<size, big_endian> > Got_entry_set;

  // Unordered set of GOT page entries.
  typedef Unordered_set<Got_page_entry*,
      Got_page_entry_hash, Got_page_entry_eq> Got_page_entry_set;

  // Unordered set of global GOT entries.
  typedef Unordered_set<Mips_symbol<size>*, Mips_symbol_hash<size> >
      Global_got_entry_set;

 public:
  Mips_got_info()
    : local_gotno_(0), page_gotno_(0), global_gotno_(0), reloc_only_gotno_(0),
      tls_gotno_(0), tls_ldm_offset_(-1U), global_got_symbols_(),
      got_entries_(), got_page_entries_(), got_page_offset_start_(0),
      got_page_offset_next_(0), got_page_offsets_(), next_(NULL), index_(-1U),
      offset_(0)
  { }

  // Reserve GOT entry for a GOT relocation of type R_TYPE against symbol
  // SYMNDX + ADDEND, where SYMNDX is a local symbol in section SHNDX in OBJECT.
  void
  record_local_got_symbol(Mips_relobj<size, big_endian>* object,
                          unsigned int symndx, Mips_address addend,
                          unsigned int r_type, unsigned int shndx,
                          bool is_section_symbol);

  // Reserve GOT entry for a GOT relocation of type R_TYPE against MIPS_SYM,
  // in OBJECT.  FOR_CALL is true if the caller is only interested in
  // using the GOT entry for calls.  DYN_RELOC is true if R_TYPE is a dynamic
  // relocation.
  void
  record_global_got_symbol(Mips_symbol<size>* mips_sym,
                           Mips_relobj<size, big_endian>* object,
                           unsigned int r_type, bool dyn_reloc, bool for_call);

  // Add ENTRY to master GOT and to OBJECT's GOT.
  void
  record_got_entry(Mips_got_entry<size, big_endian>* entry,
                   Mips_relobj<size, big_endian>* object);

  // Record that OBJECT has a page relocation against symbol SYMNDX and
  // that ADDEND is the addend for that relocation.
  void
  record_got_page_entry(Mips_relobj<size, big_endian>* object,
                        unsigned int symndx, int addend);

  // Create all entries that should be in the local part of the GOT.
  void
  add_local_entries(Target_mips<size, big_endian>* target, Layout* layout);

  // Create GOT page entries.
  void
  add_page_entries(Target_mips<size, big_endian>* target, Layout* layout);

  // Create global GOT entries, both GGA_NORMAL and GGA_RELOC_ONLY.
  void
  add_global_entries(Target_mips<size, big_endian>* target, Layout* layout,
                     unsigned int non_reloc_only_global_gotno);

  // Create global GOT entries that should be in the GGA_RELOC_ONLY area.
  void
  add_reloc_only_entries(Mips_output_data_got<size, big_endian>* got);

  // Create TLS GOT entries.
  void
  add_tls_entries(Target_mips<size, big_endian>* target, Layout* layout);

  // Decide whether the symbol needs an entry in the global part of the primary
  // GOT, setting global_got_area accordingly.  Count the number of global
  // symbols that are in the primary GOT only because they have dynamic
  // relocations R_MIPS_REL32 against them (reloc_only_gotno).
  void
  count_got_symbols(Symbol_table* symtab);

  // Return the offset of GOT page entry for VALUE.
  unsigned int
  get_got_page_offset(Mips_address value,
                      Mips_output_data_got<size, big_endian>* got);

  // Count the number of GOT entries required.
  void
  count_got_entries();

  // Count the number of GOT entries required by ENTRY.  Accumulate the result.
  void
  count_got_entry(Mips_got_entry<size, big_endian>* entry);

  // Add FROM's GOT entries.
  void
  add_got_entries(Mips_got_info<size, big_endian>* from);

  // Add FROM's GOT page entries.
  void
  add_got_page_entries(Mips_got_info<size, big_endian>* from);

  // Return GOT size.
  unsigned int
  got_size() const
  { return ((2 + this->local_gotno_ + this->page_gotno_ + this->global_gotno_
             + this->tls_gotno_) * size/8);
  }

  // Return the number of local GOT entries.
  unsigned int
  local_gotno() const
  { return this->local_gotno_; }

  // Return the maximum number of page GOT entries needed.
  unsigned int
  page_gotno() const
  { return this->page_gotno_; }

  // Return the number of global GOT entries.
  unsigned int
  global_gotno() const
  { return this->global_gotno_; }

  // Set the number of global GOT entries.
  void
  set_global_gotno(unsigned int global_gotno)
  { this->global_gotno_ = global_gotno; }

  // Return the number of GGA_RELOC_ONLY global GOT entries.
  unsigned int
  reloc_only_gotno() const
  { return this->reloc_only_gotno_; }

  // Return the number of TLS GOT entries.
  unsigned int
  tls_gotno() const
  { return this->tls_gotno_; }

  // Return the GOT type for this GOT.  Used for multi-GOT links only.
  unsigned int
  multigot_got_type(unsigned int got_type) const
  {
    switch (got_type)
      {
      case GOT_TYPE_STANDARD:
        return GOT_TYPE_STANDARD_MULTIGOT + this->index_;
      case GOT_TYPE_TLS_OFFSET:
        return GOT_TYPE_TLS_OFFSET_MULTIGOT + this->index_;
      case GOT_TYPE_TLS_PAIR:
        return GOT_TYPE_TLS_PAIR_MULTIGOT + this->index_;
      default:
        gold_unreachable();
      }
  }

  // Remove lazy-binding stubs for global symbols in this GOT.
  void
  remove_lazy_stubs(Target_mips<size, big_endian>* target);

  // Return offset of this GOT from the start of .got section.
  unsigned int
  offset() const
  { return this->offset_; }

  // Set offset of this GOT from the start of .got section.
  void
  set_offset(unsigned int offset)
  { this->offset_ = offset; }

  // Set index of this GOT in multi-GOT links.
  void
  set_index(unsigned int index)
  { this->index_ = index; }

  // Return next GOT in multi-GOT links.
  Mips_got_info<size, big_endian>*
  next() const
  { return this->next_; }

  // Set next GOT in multi-GOT links.
  void
  set_next(Mips_got_info<size, big_endian>* next)
  { this->next_ = next; }

  // Return the offset of TLS LDM entry for this GOT.
  unsigned int
  tls_ldm_offset() const
  { return this->tls_ldm_offset_; }

  // Set the offset of TLS LDM entry for this GOT.
  void
  set_tls_ldm_offset(unsigned int tls_ldm_offset)
  { this->tls_ldm_offset_ = tls_ldm_offset; }

  Global_got_entry_set&
  global_got_symbols()
  { return this->global_got_symbols_; }

  // Return the GOT_TLS_* type required by relocation type R_TYPE.
  static int
  mips_elf_reloc_tls_type(unsigned int r_type)
  {
    if (tls_gd_reloc(r_type))
      return GOT_TLS_GD;

    if (tls_ldm_reloc(r_type))
      return GOT_TLS_LDM;

    if (tls_gottprel_reloc(r_type))
      return GOT_TLS_IE;

    return GOT_TLS_NONE;
  }

  // Return the number of GOT slots needed for GOT TLS type TYPE.
  static int
  mips_tls_got_entries(unsigned int type)
  {
    switch (type)
      {
      case GOT_TLS_GD:
      case GOT_TLS_LDM:
        return 2;

      case GOT_TLS_IE:
        return 1;

      case GOT_TLS_NONE:
        return 0;

      default:
        gold_unreachable();
      }
  }

 private:
  // The number of local GOT entries.
  unsigned int local_gotno_;
  // The maximum number of page GOT entries needed.
  unsigned int page_gotno_;
  // The number of global GOT entries.
  unsigned int global_gotno_;
  // The number of global GOT entries that are in the GGA_RELOC_ONLY area.
  unsigned int reloc_only_gotno_;
  // The number of TLS GOT entries.
  unsigned int tls_gotno_;
  // The offset of TLS LDM entry for this GOT.
  unsigned int tls_ldm_offset_;
  // All symbols that have global GOT entry.
  Global_got_entry_set global_got_symbols_;
  // A hash table holding GOT entries.
  Got_entry_set got_entries_;
  // A hash table of GOT page entries.
  Got_page_entry_set got_page_entries_;
  // The offset of first GOT page entry for this GOT.
  unsigned int got_page_offset_start_;
  // The offset of next available GOT page entry for this GOT.
  unsigned int got_page_offset_next_;
  // A hash table that maps GOT page entry value to the GOT offset where
  // the entry is located.
  Got_page_offsets got_page_offsets_;
  // In multi-GOT links, a pointer to the next GOT.
  Mips_got_info<size, big_endian>* next_;
  // Index of this GOT in multi-GOT links.
  unsigned int index_;
  // The offset of this GOT in multi-GOT links.
  unsigned int offset_;
};

// This is a helper class used during relocation scan.  It records GOT16 addend.

template<int size, bool big_endian>
struct got16_addend
{
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address;

  got16_addend(const Sized_relobj_file<size, big_endian>* _object,
               unsigned int _shndx, unsigned int _r_type, unsigned int _r_sym,
               Mips_address _addend)
    : object(_object), shndx(_shndx), r_type(_r_type), r_sym(_r_sym),
      addend(_addend)
  { }

  const Sized_relobj_file<size, big_endian>* object;
  unsigned int shndx;
  unsigned int r_type;
  unsigned int r_sym;
  Mips_address addend;
};

// .MIPS.abiflags section content

template<bool big_endian>
struct Mips_abiflags
{
  typedef typename elfcpp::Swap<8, big_endian>::Valtype Valtype8;
  typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype16;
  typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype32;

  Mips_abiflags()
    : version(0), isa_level(0), isa_rev(0), gpr_size(0), cpr1_size(0),
      cpr2_size(0), fp_abi(0), isa_ext(0), ases(0), flags1(0), flags2(0)
  { }

  // Version of flags structure.
  Valtype16 version;
  // The level of the ISA: 1-5, 32, 64.
  Valtype8 isa_level;
  // The revision of ISA: 0 for MIPS V and below, 1-n otherwise.
  Valtype8 isa_rev;
  // The size of general purpose registers.
  Valtype8 gpr_size;
  // The size of co-processor 1 registers.
  Valtype8 cpr1_size;
  // The size of co-processor 2 registers.
  Valtype8 cpr2_size;
  // The floating-point ABI.
  Valtype8 fp_abi;
  // Processor-specific extension.
  Valtype32 isa_ext;
  // Mask of ASEs used.
  Valtype32 ases;
  // Mask of general flags.
  Valtype32 flags1;
  Valtype32 flags2;
};

// Mips_symbol class.  Holds additional symbol information needed for Mips.

template<int size>
class Mips_symbol : public Sized_symbol<size>
{
 public:
  Mips_symbol()
    : need_fn_stub_(false), has_nonpic_branches_(false), la25_stub_offset_(-1U),
      has_static_relocs_(false), no_lazy_stub_(false), lazy_stub_offset_(0),
      pointer_equality_needed_(false), global_got_area_(GGA_NONE),
      global_gotoffset_(-1U), got_only_for_calls_(true), has_lazy_stub_(false),
      needs_mips_plt_(false), needs_comp_plt_(false), mips_plt_offset_(-1U),
      comp_plt_offset_(-1U), mips16_fn_stub_(NULL), mips16_call_stub_(NULL),
      mips16_call_fp_stub_(NULL), applied_secondary_got_fixup_(false)
  { }

  // Return whether this is a MIPS16 symbol.
  bool
  is_mips16() const
  {
    // (st_other & STO_MIPS16) == STO_MIPS16
    return ((this->nonvis() & (elfcpp::STO_MIPS16 >> 2))
            == elfcpp::STO_MIPS16 >> 2);
  }

  // Return whether this is a microMIPS symbol.
  bool
  is_micromips() const
  {
    // (st_other & STO_MIPS_ISA) == STO_MICROMIPS
    return ((this->nonvis() & (elfcpp::STO_MIPS_ISA >> 2))
            == elfcpp::STO_MICROMIPS >> 2);
  }

  // Return whether the symbol needs MIPS16 fn_stub.
  bool
  need_fn_stub() const
  { return this->need_fn_stub_; }

  // Set that the symbol needs MIPS16 fn_stub.
  void
  set_need_fn_stub()
  { this->need_fn_stub_ = true; }

  // Return whether this symbol is referenced by branch relocations from
  // any non-PIC input file.
  bool
  has_nonpic_branches() const
  { return this->has_nonpic_branches_; }

  // Set that this symbol is referenced by branch relocations from
  // any non-PIC input file.
  void
  set_has_nonpic_branches()
  { this->has_nonpic_branches_ = true; }

  // Return the offset of the la25 stub for this symbol from the start of the
  // la25 stub section.
  unsigned int
  la25_stub_offset() const
  { return this->la25_stub_offset_; }

  // Set the offset of the la25 stub for this symbol from the start of the
  // la25 stub section.
  void
  set_la25_stub_offset(unsigned int offset)
  { this->la25_stub_offset_ = offset; }

  // Return whether the symbol has la25 stub.  This is true if this symbol is
  // for a PIC function, and there are non-PIC branches and jumps to it.
  bool
  has_la25_stub() const
  { return this->la25_stub_offset_ != -1U; }

  // Return whether there is a relocation against this symbol that must be
  // resolved by the static linker (that is, the relocation cannot possibly
  // be made dynamic).
  bool
  has_static_relocs() const
  { return this->has_static_relocs_; }

  // Set that there is a relocation against this symbol that must be resolved
  // by the static linker (that is, the relocation cannot possibly be made
  // dynamic).
  void
  set_has_static_relocs()
  { this->has_static_relocs_ = true; }

  // Return whether we must not create a lazy-binding stub for this symbol.
  bool
  no_lazy_stub() const
  { return this->no_lazy_stub_; }

  // Set that we must not create a lazy-binding stub for this symbol.
  void
  set_no_lazy_stub()
  { this->no_lazy_stub_ = true; }

  // Return the offset of the lazy-binding stub for this symbol from the start
  // of .MIPS.stubs section.
  unsigned int
  lazy_stub_offset() const
  { return this->lazy_stub_offset_; }

  // Set the offset of the lazy-binding stub for this symbol from the start
  // of .MIPS.stubs section.
  void
  set_lazy_stub_offset(unsigned int offset)
  { this->lazy_stub_offset_ = offset; }

  // Return whether there are any relocations for this symbol where
  // pointer equality matters.
  bool
  pointer_equality_needed() const
  { return this->pointer_equality_needed_; }

  // Set that there are relocations for this symbol where pointer equality
  // matters.
  void
  set_pointer_equality_needed()
  { this->pointer_equality_needed_ = true; }

  // Return global GOT area where this symbol in located.
  Global_got_area
  global_got_area() const
  { return this->global_got_area_; }

  // Set global GOT area where this symbol in located.
  void
  set_global_got_area(Global_got_area global_got_area)
  { this->global_got_area_ = global_got_area; }

  // Return the global GOT offset for this symbol.  For multi-GOT links, this
  // returns the offset from the start of .got section to the first GOT entry
  // for the symbol.  Note that in multi-GOT links the symbol can have entry
  // in more than one GOT.
  unsigned int
  global_gotoffset() const
  { return this->global_gotoffset_; }

  // Set the global GOT offset for this symbol.  Note that in multi-GOT links
  // the symbol can have entry in more than one GOT.  This method will set
  // the offset only if it is less than current offset.
  void
  set_global_gotoffset(unsigned int offset)
  {
    if (this->global_gotoffset_ == -1U || offset < this->global_gotoffset_)
      this->global_gotoffset_ = offset;
  }

  // Return whether all GOT relocations for this symbol are for calls.
  bool
  got_only_for_calls() const
  { return this->got_only_for_calls_; }

  // Set that there is a GOT relocation for this symbol that is not for call.
  void
  set_got_not_only_for_calls()
  { this->got_only_for_calls_ = false; }

  // Return whether this is a PIC symbol.
  bool
  is_pic() const
  {
    // (st_other & STO_MIPS_FLAGS) == STO_MIPS_PIC
    return ((this->nonvis() & (elfcpp::STO_MIPS_FLAGS >> 2))
            == (elfcpp::STO_MIPS_PIC >> 2));
  }

  // Set the flag in st_other field that marks this symbol as PIC.
  void
  set_pic()
  {
    if (this->is_mips16())
      // (st_other & ~(STO_MIPS16 | STO_MIPS_FLAGS)) | STO_MIPS_PIC
      this->set_nonvis((this->nonvis()
                        & ~((elfcpp::STO_MIPS16 >> 2)
                            | (elfcpp::STO_MIPS_FLAGS >> 2)))
                       | (elfcpp::STO_MIPS_PIC >> 2));
    else
      // (other & ~STO_MIPS_FLAGS) | STO_MIPS_PIC
      this->set_nonvis((this->nonvis() & ~(elfcpp::STO_MIPS_FLAGS >> 2))
                       | (elfcpp::STO_MIPS_PIC >> 2));
  }

  // Set the flag in st_other field that marks this symbol as PLT.
  void
  set_mips_plt()
  {
    if (this->is_mips16())
      // (st_other & (STO_MIPS16 | ~STO_MIPS_FLAGS)) | STO_MIPS_PLT
      this->set_nonvis((this->nonvis()
                        & ((elfcpp::STO_MIPS16 >> 2)
                           | ~(elfcpp::STO_MIPS_FLAGS >> 2)))
                       | (elfcpp::STO_MIPS_PLT >> 2));

    else
      // (st_other & ~STO_MIPS_FLAGS) | STO_MIPS_PLT
      this->set_nonvis((this->nonvis() & ~(elfcpp::STO_MIPS_FLAGS >> 2))
                       | (elfcpp::STO_MIPS_PLT >> 2));
  }

  // Downcast a base pointer to a Mips_symbol pointer.
  static Mips_symbol<size>*
  as_mips_sym(Symbol* sym)
  { return static_cast<Mips_symbol<size>*>(sym); }

  // Downcast a base pointer to a Mips_symbol pointer.
  static const Mips_symbol<size>*
  as_mips_sym(const Symbol* sym)
  { return static_cast<const Mips_symbol<size>*>(sym); }

  // Return whether the symbol has lazy-binding stub.
  bool
  has_lazy_stub() const
  { return this->has_lazy_stub_; }

  // Set whether the symbol has lazy-binding stub.
  void
  set_has_lazy_stub(bool has_lazy_stub)
  { this->has_lazy_stub_ = has_lazy_stub; }

  // Return whether the symbol needs a standard PLT entry.
  bool
  needs_mips_plt() const
  { return this->needs_mips_plt_; }

  // Set whether the symbol needs a standard PLT entry.
  void
  set_needs_mips_plt(bool needs_mips_plt)
  { this->needs_mips_plt_ = needs_mips_plt; }

  // Return whether the symbol needs a compressed (MIPS16 or microMIPS) PLT
  // entry.
  bool
  needs_comp_plt() const
  { return this->needs_comp_plt_; }

  // Set whether the symbol needs a compressed (MIPS16 or microMIPS) PLT entry.
  void
  set_needs_comp_plt(bool needs_comp_plt)
  { this->needs_comp_plt_ = needs_comp_plt; }

  // Return standard PLT entry offset, or -1 if none.
  unsigned int
  mips_plt_offset() const
  { return this->mips_plt_offset_; }

  // Set standard PLT entry offset.
  void
  set_mips_plt_offset(unsigned int mips_plt_offset)
  { this->mips_plt_offset_ = mips_plt_offset; }

  // Return whether the symbol has standard PLT entry.
  bool
  has_mips_plt_offset() const
  { return this->mips_plt_offset_ != -1U; }

  // Return compressed (MIPS16 or microMIPS) PLT entry offset, or -1 if none.
  unsigned int
  comp_plt_offset() const
  { return this->comp_plt_offset_; }

  // Set compressed (MIPS16 or microMIPS) PLT entry offset.
  void
  set_comp_plt_offset(unsigned int comp_plt_offset)
  { this->comp_plt_offset_ = comp_plt_offset; }

  // Return whether the symbol has compressed (MIPS16 or microMIPS) PLT entry.
  bool
  has_comp_plt_offset() const
  { return this->comp_plt_offset_ != -1U; }

  // Return MIPS16 fn stub for a symbol.
  template<bool big_endian>
  Mips16_stub_section<size, big_endian>*
  get_mips16_fn_stub() const
  {
    return static_cast<Mips16_stub_section<size, big_endian>*>(mips16_fn_stub_);
  }

  // Set MIPS16 fn stub for a symbol.
  void
  set_mips16_fn_stub(Mips16_stub_section_base* stub)
  { this->mips16_fn_stub_ = stub; }

  // Return whether symbol has MIPS16 fn stub.
  bool
  has_mips16_fn_stub() const
  { return this->mips16_fn_stub_ != NULL; }

  // Return MIPS16 call stub for a symbol.
  template<bool big_endian>
  Mips16_stub_section<size, big_endian>*
  get_mips16_call_stub() const
  {
    return static_cast<Mips16_stub_section<size, big_endian>*>(
      mips16_call_stub_);
  }

  // Set MIPS16 call stub for a symbol.
  void
  set_mips16_call_stub(Mips16_stub_section_base* stub)
  { this->mips16_call_stub_ = stub; }

  // Return whether symbol has MIPS16 call stub.
  bool
  has_mips16_call_stub() const
  { return this->mips16_call_stub_ != NULL; }

  // Return MIPS16 call_fp stub for a symbol.
  template<bool big_endian>
  Mips16_stub_section<size, big_endian>*
  get_mips16_call_fp_stub() const
  {
    return static_cast<Mips16_stub_section<size, big_endian>*>(
      mips16_call_fp_stub_);
  }

  // Set MIPS16 call_fp stub for a symbol.
  void
  set_mips16_call_fp_stub(Mips16_stub_section_base* stub)
  { this->mips16_call_fp_stub_ = stub; }

  // Return whether symbol has MIPS16 call_fp stub.
  bool
  has_mips16_call_fp_stub() const
  { return this->mips16_call_fp_stub_ != NULL; }

  bool
  get_applied_secondary_got_fixup() const
  { return applied_secondary_got_fixup_; }

  void
  set_applied_secondary_got_fixup()
  { this->applied_secondary_got_fixup_ = true; }

  // Return the hash of this symbol.
  size_t
  hash() const
  {
    return gold::string_hash<char>(this->name());
  }

 private:
  // Whether the symbol needs MIPS16 fn_stub.  This is true if this symbol
  // appears in any relocs other than a 16 bit call.
  bool need_fn_stub_;

  // True if this symbol is referenced by branch relocations from
  // any non-PIC input file.  This is used to determine whether an
  // la25 stub is required.
  bool has_nonpic_branches_;

  // The offset of the la25 stub for this symbol from the start of the
  // la25 stub section.
  unsigned int la25_stub_offset_;

  // True if there is a relocation against this symbol that must be
  // resolved by the static linker (that is, the relocation cannot
  // possibly be made dynamic).
  bool has_static_relocs_;

  // Whether we must not create a lazy-binding stub for this symbol.
  // This is true if the symbol has relocations related to taking the
  // function's address.
  bool no_lazy_stub_;

  // The offset of the lazy-binding stub for this symbol from the start of
  // .MIPS.stubs section.
  unsigned int lazy_stub_offset_;

  // True if there are any relocations for this symbol where pointer equality
  // matters.
  bool pointer_equality_needed_;

  // Global GOT area where this symbol in located, or GGA_NONE if symbol is not
  // in the global part of the GOT.
  Global_got_area global_got_area_;

  // The global GOT offset for this symbol.  For multi-GOT links, this is offset
  // from the start of .got section to the first GOT entry for the symbol.
  // Note that in multi-GOT links the symbol can have entry in more than one GOT.
  unsigned int global_gotoffset_;

  // Whether all GOT relocations for this symbol are for calls.
  bool got_only_for_calls_;
  // Whether the symbol has lazy-binding stub.
  bool has_lazy_stub_;
  // Whether the symbol needs a standard PLT entry.
  bool needs_mips_plt_;
  // Whether the symbol needs a compressed (MIPS16 or microMIPS) PLT entry.
  bool needs_comp_plt_;
  // Standard PLT entry offset, or -1 if none.
  unsigned int mips_plt_offset_;
  // Compressed (MIPS16 or microMIPS) PLT entry offset, or -1 if none.
  unsigned int comp_plt_offset_;
  // MIPS16 fn stub for a symbol.
  Mips16_stub_section_base* mips16_fn_stub_;
  // MIPS16 call stub for a symbol.
  Mips16_stub_section_base* mips16_call_stub_;
  // MIPS16 call_fp stub for a symbol.
  Mips16_stub_section_base* mips16_call_fp_stub_;

  bool applied_secondary_got_fixup_;
};

// Mips16_stub_section class.

// The mips16 compiler uses a couple of special sections to handle
// floating point arguments.

// Section names that look like .mips16.fn.FNNAME contain stubs that
// copy floating point arguments from the fp regs to the gp regs and
// then jump to FNNAME.  If any 32 bit function calls FNNAME, the
// call should be redirected to the stub instead.  If no 32 bit
// function calls FNNAME, the stub should be discarded.  We need to
// consider any reference to the function, not just a call, because
// if the address of the function is taken we will need the stub,
// since the address might be passed to a 32 bit function.

// Section names that look like .mips16.call.FNNAME contain stubs
// that copy floating point arguments from the gp regs to the fp
// regs and then jump to FNNAME.  If FNNAME is a 32 bit function,
// then any 16 bit function that calls FNNAME should be redirected
// to the stub instead.  If FNNAME is not a 32 bit function, the
// stub should be discarded.

// .mips16.call.fp.FNNAME sections are similar, but contain stubs
// which call FNNAME and then copy the return value from the fp regs
// to the gp regs.  These stubs store the return address in $18 while
// calling FNNAME; any function which might call one of these stubs
// must arrange to save $18 around the call.  (This case is not
// needed for 32 bit functions that call 16 bit functions, because
// 16 bit functions always return floating point values in both
// $f0/$f1 and $2/$3.)

// Note that in all cases FNNAME might be defined statically.
// Therefore, FNNAME is not used literally.  Instead, the relocation
// information will indicate which symbol the section is for.

// We record any stubs that we find in the symbol table.

// TODO(sasa): All mips16 stub sections should be emitted in the .text section.

class Mips16_stub_section_base { };

template<int size, bool big_endian>
class Mips16_stub_section : public Mips16_stub_section_base
{
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address;

 public:
  Mips16_stub_section(Mips_relobj<size, big_endian>* object, unsigned int shndx)
    : object_(object), shndx_(shndx), r_sym_(0), gsym_(NULL),
      found_r_mips_none_(false)
  {
    gold_assert(object->is_mips16_fn_stub_section(shndx)
                || object->is_mips16_call_stub_section(shndx)
                || object->is_mips16_call_fp_stub_section(shndx));
  }

  // Return the object of this stub section.
  Mips_relobj<size, big_endian>*
  object() const
  { return this->object_; }

  // Return the size of a section.
  uint64_t
  section_size() const
  { return this->object_->section_size(this->shndx_); }

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

  // Return symbol index, if stub is for a local function.
  unsigned int
  r_sym() const
  { return this->r_sym_; }

  // Return symbol, if stub is for a global function.
  Mips_symbol<size>*
  gsym() const
  { return this->gsym_; }

  // Return whether stub is for a local function.
  bool
  is_for_local_function() const
  { return this->gsym_ == NULL; }

  // This method is called when a new relocation R_TYPE for local symbol R_SYM
  // is found in the stub section.  Try to find stub target.
  void
  new_local_reloc_found(unsigned int r_type, unsigned int r_sym)
  {
    // To find target symbol for this stub, trust the first R_MIPS_NONE
    // relocation, if any.  Otherwise trust the first relocation, whatever
    // its kind.
    if (this->found_r_mips_none_)
      return;
    if (r_type == elfcpp::R_MIPS_NONE)
      {
        this->r_sym_ = r_sym;
        this->gsym_ = NULL;
        this->found_r_mips_none_ = true;
      }
    else if (!is_target_found())
      this->r_sym_ = r_sym;
  }

  // This method is called when a new relocation R_TYPE for global symbol GSYM
  // is found in the stub section.  Try to find stub target.
  void
  new_global_reloc_found(unsigned int r_type, Mips_symbol<size>* gsym)
  {
    // To find target symbol for this stub, trust the first R_MIPS_NONE
    // relocation, if any.  Otherwise trust the first relocation, whatever
    // its kind.
    if (this->found_r_mips_none_)
      return;
    if (r_type == elfcpp::R_MIPS_NONE)
      {
        this->gsym_ = gsym;
        this->r_sym_ = 0;
        this->found_r_mips_none_ = true;
      }
    else if (!is_target_found())
      this->gsym_ = gsym;
  }

  // Return whether we found the stub target.
  bool
  is_target_found() const
  { return this->r_sym_ != 0 || this->gsym_ != NULL;  }

  // Return whether this is a fn stub.
  bool
  is_fn_stub() const
  { return this->object_->is_mips16_fn_stub_section(this->shndx_); }

  // Return whether this is a call stub.
  bool
  is_call_stub() const
  { return this->object_->is_mips16_call_stub_section(this->shndx_); }

  // Return whether this is a call_fp stub.
  bool
  is_call_fp_stub() const
  { return this->object_->is_mips16_call_fp_stub_section(this->shndx_); }

  // Return the output address.
  Mips_address
  output_address() const
  {
    return (this->object_->output_section(this->shndx_)->address()
            + this->object_->output_section_offset(this->shndx_));
  }

 private:
  // The object of this stub section.
  Mips_relobj<size, big_endian>* object_;
  // The section index of this stub section.
  unsigned int shndx_;
  // The symbol index, if stub is for a local function.
  unsigned int r_sym_;
  // The symbol, if stub is for a global function.
  Mips_symbol<size>* gsym_;
  // True if we found R_MIPS_NONE relocation in this stub.
  bool found_r_mips_none_;
};

// Mips_relobj class.

template<int size, bool big_endian>
class Mips_relobj : public Sized_relobj_file<size, big_endian>
{
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address;
  typedef std::map<unsigned int, Mips16_stub_section<size, big_endian>*>
    Mips16_stubs_int_map;
  typedef typename elfcpp::Swap<size, big_endian>::Valtype Valtype;

 public:
  Mips_relobj(const std::string& name, Input_file* input_file, off_t offset,
              const typename elfcpp::Ehdr<size, big_endian>& ehdr)
    : Sized_relobj_file<size, big_endian>(name, input_file, offset, ehdr),
      processor_specific_flags_(0), local_symbol_is_mips16_(),
      local_symbol_is_micromips_(), mips16_stub_sections_(),
      local_non_16bit_calls_(), local_16bit_calls_(), local_mips16_fn_stubs_(),
      local_mips16_call_stubs_(), gp_(0), has_reginfo_section_(false),
      merge_processor_specific_data_(true), got_info_(NULL),
      section_is_mips16_fn_stub_(), section_is_mips16_call_stub_(),
      section_is_mips16_call_fp_stub_(), pdr_shndx_(-1U),
      attributes_section_data_(NULL), abiflags_(NULL), gprmask_(0),
      cprmask1_(0), cprmask2_(0), cprmask3_(0), cprmask4_(0)
  {
    this->is_pic_ = (ehdr.get_e_flags() & elfcpp::EF_MIPS_PIC) != 0;
    this->is_n32_ = elfcpp::abi_n32(ehdr.get_e_flags());
  }

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

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

  // Downcast a base pointer to a Mips_relobj pointer.  This is
  // not type-safe but we only use Mips_relobj not the base class.
  static const Mips_relobj<size, big_endian>*
  as_mips_relobj(const Relobj* relobj)
  { return static_cast<const Mips_relobj<size, 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_; }

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

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

  // Get or create MIPS16 stub section.
  Mips16_stub_section<size, big_endian>*
  get_mips16_stub_section(unsigned int shndx)
  {
    typename Mips16_stubs_int_map::const_iterator it =
      this->mips16_stub_sections_.find(shndx);
    if (it != this->mips16_stub_sections_.end())
      return (*it).second;

    Mips16_stub_section<size, big_endian>* stub_section =
      new Mips16_stub_section<size, big_endian>(this, shndx);
    this->mips16_stub_sections_.insert(
      std::pair<unsigned int, Mips16_stub_section<size, big_endian>*>(
        stub_section->shndx(), stub_section));
    return stub_section;
  }

  // Return MIPS16 fn stub section for local symbol R_SYM, or NULL if this
  // object doesn't have fn stub for R_SYM.
  Mips16_stub_section<size, big_endian>*
  get_local_mips16_fn_stub(unsigned int r_sym) const
  {
    typename Mips16_stubs_int_map::const_iterator it =
      this->local_mips16_fn_stubs_.find(r_sym);
    if (it != this->local_mips16_fn_stubs_.end())
      return (*it).second;
    return NULL;
  }

  // Record that this object has MIPS16 fn stub for local symbol.  This method
  // is only called if we decided not to discard the stub.
  void
  add_local_mips16_fn_stub(Mips16_stub_section<size, big_endian>* stub)
  {
    gold_assert(stub->is_for_local_function());
    unsigned int r_sym = stub->r_sym();
    this->local_mips16_fn_stubs_.insert(
      std::pair<unsigned int, Mips16_stub_section<size, big_endian>*>(
        r_sym, stub));
  }

  // Return MIPS16 call stub section for local symbol R_SYM, or NULL if this
  // object doesn't have call stub for R_SYM.
  Mips16_stub_section<size, big_endian>*
  get_local_mips16_call_stub(unsigned int r_sym) const
  {
    typename Mips16_stubs_int_map::const_iterator it =
      this->local_mips16_call_stubs_.find(r_sym);
    if (it != this->local_mips16_call_stubs_.end())
      return (*it).second;
    return NULL;
  }

  // Record that this object has MIPS16 call stub for local symbol.  This method
  // is only called if we decided not to discard the stub.
  void
  add_local_mips16_call_stub(Mips16_stub_section<size, big_endian>* stub)
  {
    gold_assert(stub->is_for_local_function());
    unsigned int r_sym = stub->r_sym();
    this->local_mips16_call_stubs_.insert(
      std::pair<unsigned int, Mips16_stub_section<size, big_endian>*>(
        r_sym, stub));
  }

  // Record that we found "non 16-bit" call relocation against local symbol
  // SYMNDX.  This reloc would need to refer to a MIPS16 fn stub, if there
  // is one.
  void
  add_local_non_16bit_call(unsigned int symndx)
  { this->local_non_16bit_calls_.insert(symndx); }

  // Return true if there is any "non 16-bit" call relocation against local
  // symbol SYMNDX in this object.
  bool
  has_local_non_16bit_call_relocs(unsigned int symndx)
  {
    return (this->local_non_16bit_calls_.find(symndx)
            != this->local_non_16bit_calls_.end());
  }

  // Record that we found 16-bit call relocation R_MIPS16_26 against local
  // symbol SYMNDX.  Local MIPS16 call or call_fp stubs will only be needed
  // if there is some R_MIPS16_26 relocation that refers to the stub symbol.
  void
  add_local_16bit_call(unsigned int symndx)
  { this->local_16bit_calls_.insert(symndx); }

  // Return true if there is any 16-bit call relocation R_MIPS16_26 against local
  // symbol SYMNDX in this object.
  bool
  has_local_16bit_call_relocs(unsigned int symndx)
  {
    return (this->local_16bit_calls_.find(symndx)
            != this->local_16bit_calls_.end());
  }

  // Get gp value that was used to create this object.
  Mips_address
  gp_value() const
  { return this->gp_; }

  // Return whether the object is a PIC object.
  bool
  is_pic() const
  { return this->is_pic_; }

  // Return whether the object uses N32 ABI.
  bool
  is_n32() const
  { return this->is_n32_; }

  // Return whether the object uses N64 ABI.
  bool
  is_n64() const
  { return size == 64; }

  // Return whether the object uses NewABI conventions.
  bool
  is_newabi() const
  { return this->is_n32() || this->is_n64(); }

  // Return Mips_got_info for this object.
  Mips_got_info<size, big_endian>*
  get_got_info() const
  { return this->got_info_; }

  // Return Mips_got_info for this object.  Create new info if it doesn't exist.
  Mips_got_info<size, big_endian>*
  get_or_create_got_info()
  {
    if (!this->got_info_)
      this->got_info_ = new Mips_got_info<size, big_endian>();
    return this->got_info_;
  }

  // Set Mips_got_info for this object.
  void
  set_got_info(Mips_got_info<size, big_endian>* got_info)
  { this->got_info_ = got_info; }

  // Whether a section SHDNX is a MIPS16 stub section.  This is only valid
  // after do_read_symbols is called.
  bool
  is_mips16_stub_section(unsigned int shndx)
  {
    return (is_mips16_fn_stub_section(shndx)
            || is_mips16_call_stub_section(shndx)
            || is_mips16_call_fp_stub_section(shndx));
  }

  // Return TRUE if relocations in section SHNDX can refer directly to a
  // MIPS16 function rather than to a hard-float stub.  This is only valid
  // after do_read_symbols is called.
  bool
  section_allows_mips16_refs(unsigned int shndx)
  {
    return (this->is_mips16_stub_section(shndx) || shndx == this->pdr_shndx_);
  }

  // Whether a section SHDNX is a MIPS16 fn stub section.  This is only valid
  // after do_read_symbols is called.
  bool
  is_mips16_fn_stub_section(unsigned int shndx)
  {
    gold_assert(shndx < this->section_is_mips16_fn_stub_.size());
    return this->section_is_mips16_fn_stub_[shndx];
  }

  // Whether a section SHDNX is a MIPS16 call stub section.  This is only valid
  // after do_read_symbols is called.
  bool
  is_mips16_call_stub_section(unsigned int shndx)
  {
    gold_assert(shndx < this->section_is_mips16_call_stub_.size());
    return this->section_is_mips16_call_stub_[shndx];
  }

  // Whether a section SHDNX is a MIPS16 call_fp stub section.  This is only
  // valid after do_read_symbols is called.
  bool
  is_mips16_call_fp_stub_section(unsigned int shndx)
  {
    gold_assert(shndx < this->section_is_mips16_call_fp_stub_.size());
    return this->section_is_mips16_call_fp_stub_[shndx];
  }

  // Discard MIPS16 stub secions that are not needed.
  void
  discard_mips16_stub_sections(Symbol_table* symtab);

  // Return whether there is a .reginfo section.
  bool
  has_reginfo_section() const
  { return this->has_reginfo_section_; }

  // Return whether we want to merge processor-specific data.
  bool
  merge_processor_specific_data() const
  { return this->merge_processor_specific_data_; }

  // Return gprmask from the .reginfo section of this object.
  Valtype
  gprmask() const
  { return this->gprmask_; }

  // Return cprmask1 from the .reginfo section of this object.
  Valtype
  cprmask1() const
  { return this->cprmask1_; }

  // Return cprmask2 from the .reginfo section of this object.
  Valtype
  cprmask2() const
  { return this->cprmask2_; }

  // Return cprmask3 from the .reginfo section of this object.
  Valtype
  cprmask3() const
  { return this->cprmask3_; }

  // Return cprmask4 from the .reginfo section of this object.
  Valtype
  cprmask4() const
  { return this->cprmask4_; }

  // This is the contents of the .MIPS.abiflags section if there is one.
  Mips_abiflags<big_endian>*
  abiflags()
  { return this->abiflags_; }

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

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

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

 private:
  // The name of the options section.
  const char* mips_elf_options_section_name()
  { return this->is_newabi() ? ".MIPS.options" : ".options"; }

  // processor-specific flags in ELF file header.
  elfcpp::Elf_Word processor_specific_flags_;

  // Bit vector to tell if a local symbol is a MIPS16 symbol or not.
  // This is only valid after do_count_local_symbol is called.
  std::vector<bool> local_symbol_is_mips16_;

  // Bit vector to tell if a local symbol is a microMIPS symbol or not.
  // This is only valid after do_count_local_symbol is called.
  std::vector<bool> local_symbol_is_micromips_;

  // Map from section index to the MIPS16 stub for that section.  This contains
  // all stubs found in this object.
  Mips16_stubs_int_map mips16_stub_sections_;

  // Local symbols that have "non 16-bit" call relocation.  This relocation
  // would need to refer to a MIPS16 fn stub, if there is one.
  std::set<unsigned int> local_non_16bit_calls_;

  // Local symbols that have 16-bit call relocation R_MIPS16_26.  Local MIPS16
  // call or call_fp stubs will only be needed if there is some R_MIPS16_26
  // relocation that refers to the stub symbol.
  std::set<unsigned int> local_16bit_calls_;

  // Map from local symbol index to the MIPS16 fn stub for that symbol.
  // This contains only the stubs that we decided not to discard.
  Mips16_stubs_int_map local_mips16_fn_stubs_;

  // Map from local symbol index to the MIPS16 call stub for that symbol.
  // This contains only the stubs that we decided not to discard.
  Mips16_stubs_int_map local_mips16_call_stubs_;

  // gp value that was used to create this object.
  Mips_address gp_;
  // Whether the object is a PIC object.
  bool is_pic_ : 1;
  // Whether the object uses N32 ABI.
  bool is_n32_ : 1;
  // Whether the object contains a .reginfo section.
  bool has_reginfo_section_ : 1;
  // Whether we merge processor-specific data of this object to output.
  bool merge_processor_specific_data_ : 1;
  // The Mips_got_info for this object.
  Mips_got_info<size, big_endian>* got_info_;

  // Bit vector to tell if a section is a MIPS16 fn stub section or not.
  // This is only valid after do_read_symbols is called.
  std::vector<bool> section_is_mips16_fn_stub_;

  // Bit vector to tell if a section is a MIPS16 call stub section or not.
  // This is only valid after do_read_symbols is called.
  std::vector<bool> section_is_mips16_call_stub_;

  // Bit vector to tell if a section is a MIPS16 call_fp stub section or not.
  // This is only valid after do_read_symbols is called.
  std::vector<bool> section_is_mips16_call_fp_stub_;

  // .pdr section index.
  unsigned int pdr_shndx_;

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

  // Object abiflags if there is a .MIPS.abiflags section or NULL.
  Mips_abiflags<big_endian>* abiflags_;

  // gprmask from the .reginfo section of this object.
  Valtype gprmask_;
  // cprmask1 from the .reginfo section of this object.
  Valtype cprmask1_;
  // cprmask2 from the .reginfo section of this object.
  Valtype cprmask2_;
  // cprmask3 from the .reginfo section of this object.
  Valtype cprmask3_;
  // cprmask4 from the .reginfo section of this object.
  Valtype cprmask4_;
};

// Mips_output_data_got class.

template<int size, bool big_endian>
class Mips_output_data_got : public Output_data_got<size, big_endian>
{
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address;
  typedef Output_data_reloc<elfcpp::SHT_REL, true, size, big_endian>
    Reloc_section;
  typedef typename elfcpp::Swap<size, big_endian>::Valtype Valtype;

 public:
  Mips_output_data_got(Target_mips<size, big_endian>* target,
      Symbol_table* symtab, Layout* layout)
    : Output_data_got<size, big_endian>(), target_(target),
      symbol_table_(symtab), layout_(layout), static_relocs_(), got_view_(NULL),
      first_global_got_dynsym_index_(-1U), primary_got_(NULL),
      secondary_got_relocs_()
  {
    this->master_got_info_ = new Mips_got_info<size, big_endian>();
    this->set_addralign(16);
  }

  // Reserve GOT entry for a GOT relocation of type R_TYPE against symbol
  // SYMNDX + ADDEND, where SYMNDX is a local symbol in section SHNDX in OBJECT.
  void
  record_local_got_symbol(Mips_relobj<size, big_endian>* object,
                          unsigned int symndx, Mips_address addend,
                          unsigned int r_type, unsigned int shndx,
                          bool is_section_symbol)
  {
    this->master_got_info_->record_local_got_symbol(object, symndx, addend,
                                                    r_type, shndx,
                                                    is_section_symbol);
  }

  // Reserve GOT entry for a GOT relocation of type R_TYPE against MIPS_SYM,
  // in OBJECT.  FOR_CALL is true if the caller is only interested in
  // using the GOT entry for calls.  DYN_RELOC is true if R_TYPE is a dynamic
  // relocation.
  void
  record_global_got_symbol(Mips_symbol<size>* mips_sym,
                           Mips_relobj<size, big_endian>* object,
                           unsigned int r_type, bool dyn_reloc, bool for_call)
  {
    this->master_got_info_->record_global_got_symbol(mips_sym, object, r_type,
                                                     dyn_reloc, for_call);
  }

  // Record that OBJECT has a page relocation against symbol SYMNDX and
  // that ADDEND is the addend for that relocation.
  void
  record_got_page_entry(Mips_relobj<size, big_endian>* object,
                        unsigned int symndx, int addend)
  { this->master_got_info_->record_got_page_entry(object, symndx, addend); }

  // 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,
                   Mips_symbol<size>* gsym)
  { this->static_relocs_.push_back(Static_reloc(got_offset, r_type, gsym)); }

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

  // Record that global symbol GSYM has R_TYPE dynamic relocation in the
  // secondary GOT at OFFSET.
  void
  add_secondary_got_reloc(unsigned int got_offset, unsigned int r_type,
                          Mips_symbol<size>* gsym)
  {
    this->secondary_got_relocs_.push_back(Static_reloc(got_offset,
                                                       r_type, gsym));
  }

  // Update GOT entry at OFFSET with VALUE.
  void
  update_got_entry(unsigned int offset, Mips_address value)
  {
    elfcpp::Swap<size, big_endian>::writeval(this->got_view_ + offset, value);
  }

  // Return the number of entries in local part of the GOT.  This includes
  // local entries, page entries and 2 reserved entries.
  unsigned int
  get_local_gotno() const
  {
    if (!this->multi_got())
      {
        return (2 + this->master_got_info_->local_gotno()
                + this->master_got_info_->page_gotno());
      }
    else
      return 2 + this->primary_got_->local_gotno() + this->primary_got_->page_gotno();
  }

  // Return dynamic symbol table index of the first symbol with global GOT
  // entry.
  unsigned int
  first_global_got_dynsym_index() const
  { return this->first_global_got_dynsym_index_; }

  // Set dynamic symbol table index of the first symbol with global GOT entry.
  void
  set_first_global_got_dynsym_index(unsigned int index)
  { this->first_global_got_dynsym_index_ = index; }

  // Lay out the GOT.  Add local, global and TLS entries.  If GOT is
  // larger than 64K, create multi-GOT.
  void
  lay_out_got(Layout* layout, Symbol_table* symtab,
              const Input_objects* input_objects);

  // Create multi-GOT.  For every GOT, add local, global and TLS entries.
  void
  lay_out_multi_got(Layout* layout, const Input_objects* input_objects);

  // Attempt to merge GOTs of different input objects.
  void
  merge_gots(const Input_objects* input_objects);

  // Consider merging FROM, which is OBJECT's GOT, into TO.  Return false if
  // this would lead to overflow, true if they were merged successfully.
  bool
  merge_got_with(Mips_got_info<size, big_endian>* from,
                 Mips_relobj<size, big_endian>* object,
                 Mips_got_info<size, big_endian>* to);

  // Return the offset of GOT page entry for VALUE.  For multi-GOT links,
  // use OBJECT's GOT.
  unsigned int
  get_got_page_offset(Mips_address value,
                      const Mips_relobj<size, big_endian>* object)
  {
    Mips_got_info<size, big_endian>* g = (!this->multi_got()
                                          ? this->master_got_info_
                                          : object->get_got_info());
    gold_assert(g != NULL);
    return g->get_got_page_offset(value, this);
  }

  // Return the GOT offset of type GOT_TYPE of the global symbol
  // GSYM.  For multi-GOT links, use OBJECT's GOT.
  unsigned int got_offset(const Symbol* gsym, unsigned int got_type,
                          Mips_relobj<size, big_endian>* object) const
  {
    if (!this->multi_got())
      return gsym->got_offset(got_type);
    else
      {
        Mips_got_info<size, big_endian>* g = object->get_got_info();
        gold_assert(g != NULL);
        return gsym->got_offset(g->multigot_got_type(got_type));
      }
  }

  // Return the GOT offset of type GOT_TYPE of the local symbol
  // SYMNDX.
  unsigned int
  got_offset(unsigned int symndx, unsigned int got_type,
             Sized_relobj_file<size, big_endian>* object,
             uint64_t addend) const
  { return object->local_got_offset(symndx, got_type, addend); }

  // Return the offset of TLS LDM entry.  For multi-GOT links, use OBJECT's GOT.
  unsigned int
  tls_ldm_offset(Mips_relobj<size, big_endian>* object) const
  {
    Mips_got_info<size, big_endian>* g = (!this->multi_got()
                                          ? this->master_got_info_
                                          : object->get_got_info());
    gold_assert(g != NULL);
    return g->tls_ldm_offset();
  }

  // Set the offset of TLS LDM entry.  For multi-GOT links, use OBJECT's GOT.
  void
  set_tls_ldm_offset(unsigned int tls_ldm_offset,
                     Mips_relobj<size, big_endian>* object)
  {
    Mips_got_info<size, big_endian>* g = (!this->multi_got()
                                          ? this->master_got_info_
                                          : object->get_got_info());
    gold_assert(g != NULL);
    g->set_tls_ldm_offset(tls_ldm_offset);
  }

  // Return true for multi-GOT links.
  bool
  multi_got() const
  { return this->primary_got_ != NULL; }

  // Return the offset of OBJECT's GOT from the start of .got section.
  unsigned int
  get_got_offset(const Mips_relobj<size, big_endian>* object)
  {
    if (!this->multi_got())
      return 0;
    else
      {
        Mips_got_info<size, big_endian>* g = object->get_got_info();
        return g != NULL ? g->offset() : 0;
      }
  }

  // Create global GOT entries that should be in the GGA_RELOC_ONLY area.
  void
  add_reloc_only_entries()
  { this->master_got_info_->add_reloc_only_entries(this); }

  // Return offset of the primary GOT's entry for global symbol.
  unsigned int
  get_primary_got_offset(const Mips_symbol<size>* sym) const
  {
    gold_assert(sym->global_got_area() != GGA_NONE);
    return (this->get_local_gotno() + sym->dynsym_index()
            - this->first_global_got_dynsym_index()) * size/8;
  }

  // For the entry at offset GOT_OFFSET, return its offset from the gp.
  // Input argument GOT_OFFSET is always global offset from the start of
  // .got section, for both single and multi-GOT links.
  // For single GOT links, this returns GOT_OFFSET - 0x7FF0.  For multi-GOT
  // links, the return value is object_got_offset - 0x7FF0, where
  // object_got_offset is offset in the OBJECT's GOT.
  int
  gp_offset(unsigned int got_offset,
            const Mips_relobj<size, big_endian>* object) const
  {
    return (this->address() + got_offset
            - this->target_->adjusted_gp_value(object));
  }

 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,
                 Mips_symbol<size>* gsym)
      : got_offset_(got_offset), r_type_(r_type), symbol_is_global_(true)
    { this->u_.global.symbol = gsym; }

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

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

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

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

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

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

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

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

  // The target.
  Target_mips<size, big_endian>* target_;
  // The symbol table.
  Symbol_table* symbol_table_;
  // The layout.
  Layout* layout_;
  // Static relocs to be applied to the GOT.
  std::vector<Static_reloc> static_relocs_;
  // .got section view.
  unsigned char* got_view_;
  // The dynamic symbol table index of the first symbol with global GOT entry.
  unsigned int first_global_got_dynsym_index_;
  // The master GOT information.
  Mips_got_info<size, big_endian>* master_got_info_;
  // The  primary GOT information.
  Mips_got_info<size, big_endian>* primary_got_;
  // Secondary GOT fixups.
  std::vector<Static_reloc> secondary_got_relocs_;
};

// A class to handle LA25 stubs - non-PIC interface to a PIC function. There are
// two ways of creating these interfaces.  The first is to add:
//
//      lui     $25,%hi(func)
//      j       func
//      addiu   $25,$25,%lo(func)
//
// to a separate trampoline section.  The second is to add:
//
//      lui     $25,%hi(func)
//      addiu   $25,$25,%lo(func)
//
// immediately before a PIC function "func", but only if a function is at the
// beginning of the section, and the section is not too heavily aligned (i.e we
// would need to add no more than 2 nops before the stub.)
//
// We only create stubs of the first type.

template<int size, bool big_endian>
class Mips_output_data_la25_stub : public Output_section_data
{
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address;

 public:
  Mips_output_data_la25_stub()
  : Output_section_data(size == 32 ? 4 : 8), symbols_()
  { }

  // Create LA25 stub for a symbol.
  void
  create_la25_stub(Symbol_table* symtab, Target_mips<size, big_endian>* target,
                   Mips_symbol<size>* gsym);

  // Return output address of a stub.
  Mips_address
  stub_address(const Mips_symbol<size>* sym) const
  {
    gold_assert(sym->has_la25_stub());
    return this->address() + sym->la25_stub_offset();
  }

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

 private:
  // Template for standard LA25 stub.
  static const uint32_t la25_stub_entry[];
  // Template for microMIPS LA25 stub.
  static const uint32_t la25_stub_micromips_entry[];

  // Set the final size.
  void
  set_final_data_size()
  { this->set_data_size(this->symbols_.size() * 16); }

  // Create a symbol for SYM stub's value and size, to help make the
  // disassembly easier to read.
  void
  create_stub_symbol(Mips_symbol<size>* sym, Symbol_table* symtab,
                     Target_mips<size, big_endian>* target, uint64_t symsize);

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

  // Write out the LA25 stub section.
  void
  do_write(Output_file*);

  // Symbols that have LA25 stubs.
  std::vector<Mips_symbol<size>*> symbols_;
};

// MIPS-specific relocation writer.

template<int sh_type, bool dynamic, int size, bool big_endian>
struct Mips_output_reloc_writer;

template<int sh_type, bool dynamic, bool big_endian>
struct Mips_output_reloc_writer<sh_type, dynamic, 32, big_endian>
{
  typedef Output_reloc<sh_type, dynamic, 32, big_endian> Output_reloc_type;
  typedef std::vector<Output_reloc_type> Relocs;

  static void
  write(typename Relocs::const_iterator p, unsigned char* pov)
  { p->write(pov); }
};

template<int sh_type, bool dynamic, bool big_endian>
struct Mips_output_reloc_writer<sh_type, dynamic, 64, big_endian>
{
  typedef Output_reloc<sh_type, dynamic, 64, big_endian> Output_reloc_type;
  typedef std::vector<Output_reloc_type> Relocs;

  static void
  write(typename Relocs::const_iterator p, unsigned char* pov)
  {
    elfcpp::Mips64_rel_write<big_endian> orel(pov);
    orel.put_r_offset(p->get_address());
    orel.put_r_sym(p->get_symbol_index());
    orel.put_r_ssym(RSS_UNDEF);
    orel.put_r_type(p->type());
    if (p->type() == elfcpp::R_MIPS_REL32)
      orel.put_r_type2(elfcpp::R_MIPS_64);
    else
      orel.put_r_type2(elfcpp::R_MIPS_NONE);
    orel.put_r_type3(elfcpp::R_MIPS_NONE);
  }
};

template<int sh_type, bool dynamic, int size, bool big_endian>
class Mips_output_data_reloc : public Output_data_reloc<sh_type, dynamic,
                                                        size, big_endian>
{
 public:
  Mips_output_data_reloc(bool sort_relocs)
    : Output_data_reloc<sh_type, dynamic, size, big_endian>(sort_relocs)
  { }

 protected:
  // Write out the data.
  void
  do_write(Output_file* of)
  {
    typedef Mips_output_reloc_writer<sh_type, dynamic, size,
        big_endian> Writer;
    this->template do_write_generic<Writer>(of);
  }
};


// A class to handle the PLT data.

template<int size, bool big_endian>
class Mips_output_data_plt : public Output_section_data
{
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address;
  typedef Mips_output_data_reloc<elfcpp::SHT_REL, true,
                                 size, big_endian> Reloc_section;

 public:
  // Create the PLT section.  The ordinary .got section is an argument,
  // since we need to refer to the start.
  Mips_output_data_plt(Layout* layout, Output_data_space* got_plt,
                       Target_mips<size, big_endian>* target)
    : Output_section_data(size == 32 ? 4 : 8), got_plt_(got_plt), symbols_(),
      plt_mips_offset_(0), plt_comp_offset_(0), plt_header_size_(0),
      target_(target)
  {
    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);
  }

  // Add an entry to the PLT for a symbol referenced by r_type relocation.
  void
  add_entry(Mips_symbol<size>* gsym, unsigned int r_type);

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

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

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

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

  // Set final PLT offsets.  For each symbol, determine whether standard or
  // compressed (MIPS16 or microMIPS) PLT entry is used.
  void
  set_plt_offsets();

  // Return the offset of the first standard PLT entry.
  unsigned int
  first_mips_plt_offset() const
  { return this->plt_header_size_; }

  // Return the offset of the first compressed PLT entry.
  unsigned int
  first_comp_plt_offset() const
  { return this->plt_header_size_ + this->plt_mips_offset_; }

  // Return whether there are any standard PLT entries.
  bool
  has_standard_entries() const
  { return this->plt_mips_offset_ > 0; }

  // Return the output address of standard PLT entry.
  Mips_address
  mips_entry_address(const Mips_symbol<size>* sym) const
  {
    gold_assert (sym->has_mips_plt_offset());
    return (this->address() + this->first_mips_plt_offset()
            + sym->mips_plt_offset());
  }

  // Return the output address of compressed (MIPS16 or microMIPS) PLT entry.
  Mips_address
  comp_entry_address(const Mips_symbol<size>* sym) const
  {
    gold_assert (sym->has_comp_plt_offset());
    return (this->address() + this->first_comp_plt_offset()
            + sym->comp_plt_offset());
  }

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

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

 private:
  // Template for the first PLT entry.
  static const uint32_t plt0_entry_o32[];
  static const uint32_t plt0_entry_n32[];
  static const uint32_t plt0_entry_n64[];
  static const uint32_t plt0_entry_micromips_o32[];
  static const uint32_t plt0_entry_micromips32_o32[];

  // Template for subsequent PLT entries.
  static const uint32_t plt_entry[];
  static const uint32_t plt_entry_r6[];
  static const uint32_t plt_entry_mips16_o32[];
  static const uint32_t plt_entry_micromips_o32[];
  static const uint32_t plt_entry_micromips32_o32[];

  // Set the final size.
  void
  set_final_data_size()
  {
    this->set_data_size(this->plt_header_size_ + this->plt_mips_offset_
                        + this->plt_comp_offset_);
  }

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

  // Return whether the plt header contains microMIPS code.  For the sake of
  // cache alignment always use a standard header whenever any standard entries
  // are present even if microMIPS entries are present as well.  This also lets
  // the microMIPS header rely on the value of $v0 only set by microMIPS
  // entries, for a small size reduction.
  bool
  is_plt_header_compressed() const
  {
    gold_assert(this->plt_mips_offset_ + this->plt_comp_offset_ != 0);
    return this->target_->is_output_micromips() && this->plt_mips_offset_ == 0;
  }

  // Return the size of the PLT header.
  unsigned int
  get_plt_header_size() const
  {
    if (this->target_->is_output_n64())
      return 4 * sizeof(plt0_entry_n64) / sizeof(plt0_entry_n64[0]);
    else if (this->target_->is_output_n32())
      return 4 * sizeof(plt0_entry_n32) / sizeof(plt0_entry_n32[0]);
    else if (!this->is_plt_header_compressed())
      return 4 * sizeof(plt0_entry_o32) / sizeof(plt0_entry_o32[0]);
    else if (this->target_->use_32bit_micromips_instructions())
      return (2 * sizeof(plt0_entry_micromips32_o32)
              / sizeof(plt0_entry_micromips32_o32[0]));
    else
      return (2 * sizeof(plt0_entry_micromips_o32)
              / sizeof(plt0_entry_micromips_o32[0]));
  }

  // Return the PLT header entry.
  const uint32_t*
  get_plt_header_entry() const
  {
    if (this->target_->is_output_n64())
      return plt0_entry_n64;
    else if (this->target_->is_output_n32())
      return plt0_entry_n32;
    else if (!this->is_plt_header_compressed())
      return plt0_entry_o32;
    else if (this->target_->use_32bit_micromips_instructions())
      return plt0_entry_micromips32_o32;
    else
      return plt0_entry_micromips_o32;
  }

  // Return the size of the standard PLT entry.
  unsigned int
  standard_plt_entry_size() const
  { return 4 * sizeof(plt_entry) / sizeof(plt_entry[0]); }

  // Return the size of the compressed PLT entry.
  unsigned int
  compressed_plt_entry_size() const
  {
    gold_assert(!this->target_->is_output_newabi());

    if (!this->target_->is_output_micromips())
      return (2 * sizeof(plt_entry_mips16_o32)
              / sizeof(plt_entry_mips16_o32[0]));
    else if (this->target_->use_32bit_micromips_instructions())
      return (2 * sizeof(plt_entry_micromips32_o32)
              / sizeof(plt_entry_micromips32_o32[0]));
    else
      return (2 * sizeof(plt_entry_micromips_o32)
              / sizeof(plt_entry_micromips_o32[0]));
  }

  // The reloc section.
  Reloc_section* rel_;
  // The .got.plt section.
  Output_data_space* got_plt_;
  // Symbols that have PLT entry.
  std::vector<Mips_symbol<size>*> symbols_;
  // The offset of the next standard PLT entry to create.
  unsigned int plt_mips_offset_;
  // The offset of the next compressed PLT entry to create.
  unsigned int plt_comp_offset_;
  // The size of the PLT header in bytes.
  unsigned int plt_header_size_;
  // The target.
  Target_mips<size, big_endian>* target_;
};

// A class to handle the .MIPS.stubs data.

template<int size, bool big_endian>
class Mips_output_data_mips_stubs : public Output_section_data
{
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address;

  // Unordered set of .MIPS.stubs entries.
  typedef Unordered_set<Mips_symbol<size>*, Mips_symbol_hash<size> >
      Mips_stubs_entry_set;

 public:
   Mips_output_data_mips_stubs(Target_mips<size, big_endian>* target)
     : Output_section_data(size == 32 ? 4 : 8), symbols_(), dynsym_count_(-1U),
       stub_offsets_are_set_(false), target_(target)
   { }

  // Create entry for a symbol.
  void
  make_entry(Mips_symbol<size>*);

  // Remove entry for a symbol.
  void
  remove_entry(Mips_symbol<size>* gsym);

  // Set stub offsets for symbols.  This method expects that the number of
  // entries in dynamic symbol table is set.
  void
  set_lazy_stub_offsets();

  void
  set_needs_dynsym_value();

   // Set the number of entries in dynamic symbol table.
  void
  set_dynsym_count(unsigned int dynsym_count)
  { this->dynsym_count_ = dynsym_count; }

  // Return maximum size of the stub, ie. the stub size if the dynamic symbol
  // count is greater than 0x10000.  If the dynamic symbol count is less than
  // 0x10000, the stub will be 4 bytes smaller.
  // There's no disadvantage from using microMIPS code here, so for the sake of
  // pure-microMIPS binaries we prefer it whenever there's any microMIPS code in
  // output produced at all.  This has a benefit of stubs being shorter by
  // 4 bytes each too, unless in the insn32 mode.
  unsigned int
  stub_max_size() const
  {
    if (!this->target_->is_output_micromips()
        || this->target_->use_32bit_micromips_instructions())
      return 20;
    else
      return 16;
  }

  // Return the size of the stub.  This method expects that the final dynsym
  // count is set.
  unsigned int
  stub_size() const
  {
    gold_assert(this->dynsym_count_ != -1U);
    if (this->dynsym_count_ > 0x10000)
      return this->stub_max_size();
    else
      return this->stub_max_size() - 4;
  }

  // Return output address of a stub.
  Mips_address
  stub_address(const Mips_symbol<size>* sym) const
  {
    gold_assert(sym->has_lazy_stub());
    return this->address() + sym->lazy_stub_offset();
  }

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

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

 private:
  static const uint32_t lazy_stub_normal_1[];
  static const uint32_t lazy_stub_normal_1_n64[];
  static const uint32_t lazy_stub_normal_2[];
  static const uint32_t lazy_stub_normal_2_n64[];
  static const uint32_t lazy_stub_big[];
  static const uint32_t lazy_stub_big_n64[];

  static const uint32_t lazy_stub_micromips_normal_1[];
  static const uint32_t lazy_stub_micromips_normal_1_n64[];
  static const uint32_t lazy_stub_micromips_normal_2[];
  static const uint32_t lazy_stub_micromips_normal_2_n64[];
  static const uint32_t lazy_stub_micromips_big[];
  static const uint32_t lazy_stub_micromips_big_n64[];

  static const uint32_t lazy_stub_micromips32_normal_1[];
  static const uint32_t lazy_stub_micromips32_normal_1_n64[];
  static const uint32_t lazy_stub_micromips32_normal_2[];
  static const uint32_t lazy_stub_micromips32_normal_2_n64[];
  static const uint32_t lazy_stub_micromips32_big[];
  static const uint32_t lazy_stub_micromips32_big_n64[];

  // Set the final size.
  void
  set_final_data_size()
  { this->set_data_size(this->symbols_.size() * this->stub_max_size()); }

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

  // .MIPS.stubs symbols
  Mips_stubs_entry_set symbols_;
  // Number of entries in dynamic symbol table.
  unsigned int dynsym_count_;
  // Whether the stub offsets are set.
  bool stub_offsets_are_set_;
  // The target.
  Target_mips<size, big_endian>* target_;
};

// This class handles Mips .reginfo output section.

template<int size, bool big_endian>
class Mips_output_section_reginfo : public Output_section_data
{
  typedef typename elfcpp::Swap<size, big_endian>::Valtype Valtype;

 public:
  Mips_output_section_reginfo(Target_mips<size, big_endian>* target,
                              Valtype gprmask, Valtype cprmask1,
                              Valtype cprmask2, Valtype cprmask3,
                              Valtype cprmask4)
    : Output_section_data(24, 4, true), target_(target),
      gprmask_(gprmask), cprmask1_(cprmask1), cprmask2_(cprmask2),
      cprmask3_(cprmask3), cprmask4_(cprmask4)
  { }

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

  // Write out reginfo section.
  void
  do_write(Output_file* of);

 private:
  Target_mips<size, big_endian>* target_;

  // gprmask of the output .reginfo section.
  Valtype gprmask_;
  // cprmask1 of the output .reginfo section.
  Valtype cprmask1_;
  // cprmask2 of the output .reginfo section.
  Valtype cprmask2_;
  // cprmask3 of the output .reginfo section.
  Valtype cprmask3_;
  // cprmask4 of the output .reginfo section.
  Valtype cprmask4_;
};

// This class handles .MIPS.options output section.

template<int size, bool big_endian>
class Mips_output_section_options : public Output_section
{
 public:
  Mips_output_section_options(const char* name, elfcpp::Elf_Word type,
                              elfcpp::Elf_Xword flags,
                              Target_mips<size, big_endian>* target)
    : Output_section(name, type, flags), target_(target)
  {
    // After the input sections are written, we only need to update
    // ri_gp_value field of ODK_REGINFO entries.
    this->set_after_input_sections();
  }

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

 private:
  Target_mips<size, big_endian>* target_;
};

// This class handles .MIPS.abiflags output section.

template<int size, bool big_endian>
class Mips_output_section_abiflags : public Output_section_data
{
 public:
  Mips_output_section_abiflags(const Mips_abiflags<big_endian>& abiflags)
    : Output_section_data(24, 8, true), abiflags_(abiflags)
  { }

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

  void
  do_write(Output_file* of);

 private:
  const Mips_abiflags<big_endian>& abiflags_;
};

// The MIPS target has relocation types which default handling of relocatable
// relocation cannot process.  So we have to extend the default code.

template<bool big_endian, typename Classify_reloc>
class Mips_scan_relocatable_relocs :
  public Default_scan_relocatable_relocs<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* object)
  {
    if (Classify_reloc::sh_type == elfcpp::SHT_RELA)
      return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA;
    else
      {
        switch (r_type)
          {
          case elfcpp::R_MIPS_26:
            return Relocatable_relocs::RELOC_SPECIAL;

          default:
            return Default_scan_relocatable_relocs<Classify_reloc>::
                local_section_strategy(r_type, object);
          }
      }
  }
};

// Mips_copy_relocs class.  The only difference from the base class is the
// method emit_mips, which should be called instead of Copy_reloc_entry::emit.
// Mips cannot convert all relocation types to dynamic relocs.  If a reloc
// cannot be made dynamic, a COPY reloc is emitted.

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

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

 private:
  typedef typename Copy_relocs<sh_type, size, big_endian>::Copy_reloc_entry
    Copy_reloc_entry;

  // Emit this reloc if appropriate.  This is called after we have
  // scanned all the relocations, so we know whether we emitted a
  // COPY relocation for SYM_.
  void
  emit_entry(Copy_reloc_entry& entry,
             Output_data_reloc<sh_type, true, size, big_endian>* reloc_section,
             Symbol_table* symtab, Layout* layout,
             Target_mips<size, big_endian>* target);
};


// Return true if the symbol SYM should be considered to resolve local
// to the current module, and false otherwise.  The logic is taken from
// GNU ld's method _bfd_elf_symbol_refs_local_p.
static bool
symbol_refs_local(const Symbol* sym, bool has_dynsym_entry,
                  bool local_protected)
{
  // If it's a local sym, of course we resolve locally.
  if (sym == NULL)
    return true;

  // STV_HIDDEN or STV_INTERNAL ones must be local.
  if (sym->visibility() == elfcpp::STV_HIDDEN
      || sym->visibility() == elfcpp::STV_INTERNAL)
    return true;

  // If we don't have a definition in a regular file, then we can't
  // resolve locally.  The sym is either undefined or dynamic.
  if (sym->is_from_dynobj() || sym->is_undefined())
    return false;

  // Forced local symbols resolve locally.
  if (sym->is_forced_local())
    return true;

  // As do non-dynamic symbols.
  if (!has_dynsym_entry)
    return true;

  // At this point, we know the symbol is defined and dynamic.  In an
  // executable it must resolve locally, likewise when building symbolic
  // shared libraries.
  if (parameters->options().output_is_executable()
      || parameters->options().Bsymbolic())
    return true;

  // Now deal with defined dynamic symbols in shared libraries.  Ones
  // with default visibility might not resolve locally.
  if (sym->visibility() == elfcpp::STV_DEFAULT)
    return false;

  // STV_PROTECTED non-function symbols are local.
  if (sym->type() != elfcpp::STT_FUNC)
    return true;

  // Function pointer equality tests may require that STV_PROTECTED
  // symbols be treated as dynamic symbols.  If the address of a
  // function not defined in an executable is set to that function's
  // plt entry in the executable, then the address of the function in
  // a shared library must also be the plt entry in the executable.
  return local_protected;
}

// Return TRUE if references to this symbol always reference the symbol in this
// object.
static bool
symbol_references_local(const Symbol* sym, bool has_dynsym_entry)
{
  return symbol_refs_local(sym, has_dynsym_entry, false);
}

// Return TRUE if calls to this symbol always call the version in this object.
static bool
symbol_calls_local(const Symbol* sym, bool has_dynsym_entry)
{
  return symbol_refs_local(sym, has_dynsym_entry, true);
}

// Compare GOT offsets of two symbols.

template<int size, bool big_endian>
static bool
got_offset_compare(Symbol* sym1, Symbol* sym2)
{
  Mips_symbol<size>* mips_sym1 = Mips_symbol<size>::as_mips_sym(sym1);
  Mips_symbol<size>* mips_sym2 = Mips_symbol<size>::as_mips_sym(sym2);
  unsigned int area1 = mips_sym1->global_got_area();
  unsigned int area2 = mips_sym2->global_got_area();
  gold_assert(area1 != GGA_NONE && area1 != GGA_NONE);

  // GGA_NORMAL entries always come before GGA_RELOC_ONLY.
  if (area1 != area2)
    return area1 < area2;

  return mips_sym1->global_gotoffset() < mips_sym2->global_gotoffset();
}

// This method divides dynamic symbols into symbols that have GOT entry, and
// symbols that don't have GOT entry.  It also sorts symbols with the GOT entry.
// Mips ABI requires that symbols with the GOT entry must be at the end of
// dynamic symbol table, and the order in dynamic symbol table must match the
// order in GOT.

template<int size, bool big_endian>
static void
reorder_dyn_symbols(std::vector<Symbol*>* dyn_symbols,
                    std::vector<Symbol*>* non_got_symbols,
                    std::vector<Symbol*>* got_symbols)
{
  for (std::vector<Symbol*>::iterator p = dyn_symbols->begin();
       p != dyn_symbols->end();
       ++p)
    {
      Mips_symbol<size>* mips_sym = Mips_symbol<size>::as_mips_sym(*p);
      if (mips_sym->global_got_area() == GGA_NORMAL
          || mips_sym->global_got_area() == GGA_RELOC_ONLY)
        got_symbols->push_back(mips_sym);
      else
        non_got_symbols->push_back(mips_sym);
    }

  std::sort(got_symbols->begin(), got_symbols->end(),
            got_offset_compare<size, big_endian>);
}

// Functor class for processing the global symbol table.

template<int size, bool big_endian>
class Symbol_visitor_check_symbols
{
 public:
  Symbol_visitor_check_symbols(Target_mips<size, big_endian>* target,
    Layout* layout, Symbol_table* symtab)
    : target_(target), layout_(layout), symtab_(symtab)
  { }

  void
  operator()(Sized_symbol<size>* sym)
  {
    Mips_symbol<size>* mips_sym = Mips_symbol<size>::as_mips_sym(sym);
    if (local_pic_function<size, big_endian>(mips_sym))
      {
        // SYM is a function that might need $25 to be valid on entry.
        // If we're creating a non-PIC relocatable object, mark SYM as
        // being PIC.  If we're creating a non-relocatable object with
        // non-PIC branches and jumps to SYM, make sure that SYM has an la25
        // stub.
        if (parameters->options().relocatable())
          {
            if (!parameters->options().output_is_position_independent())
              mips_sym->set_pic();
          }
        else if (mips_sym->has_nonpic_branches())
          {
            this->target_->la25_stub_section(layout_)
                ->create_la25_stub(this->symtab_, this->target_, mips_sym);
          }
      }
  }

 private:
  Target_mips<size, big_endian>* target_;
  Layout* layout_;
  Symbol_table* symtab_;
};

// Relocation types, parameterized by SHT_REL vs. SHT_RELA, size,
// and endianness. The relocation format for MIPS-64 is non-standard.

template<int sh_type, int size, bool big_endian>
struct Mips_reloc_types;

template<bool big_endian>
struct Mips_reloc_types<elfcpp::SHT_REL, 32, big_endian>
{
  typedef typename elfcpp::Rel<32, big_endian> Reloc;
  typedef typename elfcpp::Rel_write<32, big_endian> Reloc_write;

  static typename elfcpp::Elf_types<32>::Elf_Swxword
  get_r_addend(const Reloc*)
  { return 0; }

  static inline void
  set_reloc_addend(Reloc_write*,
		   typename elfcpp::Elf_types<32>::Elf_Swxword)
  { gold_unreachable(); }
};

template<bool big_endian>
struct Mips_reloc_types<elfcpp::SHT_RELA, 32, big_endian>
{
  typedef typename elfcpp::Rela<32, big_endian> Reloc;
  typedef typename elfcpp::Rela_write<32, big_endian> Reloc_write;

  static typename elfcpp::Elf_types<32>::Elf_Swxword
  get_r_addend(const Reloc* reloc)
  { return reloc->get_r_addend(); }

  static inline void
  set_reloc_addend(Reloc_write* p,
		   typename elfcpp::Elf_types<32>::Elf_Swxword val)
  { p->put_r_addend(val); }
};

template<bool big_endian>
struct Mips_reloc_types<elfcpp::SHT_REL, 64, big_endian>
{
  typedef typename elfcpp::Mips64_rel<big_endian> Reloc;
  typedef typename elfcpp::Mips64_rel_write<big_endian> Reloc_write;

  static typename elfcpp::Elf_types<64>::Elf_Swxword
  get_r_addend(const Reloc*)
  { return 0; }

  static inline void
  set_reloc_addend(Reloc_write*,
		   typename elfcpp::Elf_types<64>::Elf_Swxword)
  { gold_unreachable(); }
};

template<bool big_endian>
struct Mips_reloc_types<elfcpp::SHT_RELA, 64, big_endian>
{
  typedef typename elfcpp::Mips64_rela<big_endian> Reloc;
  typedef typename elfcpp::Mips64_rela_write<big_endian> Reloc_write;

  static typename elfcpp::Elf_types<64>::Elf_Swxword
  get_r_addend(const Reloc* reloc)
  { return reloc->get_r_addend(); }

  static inline void
  set_reloc_addend(Reloc_write* p,
		   typename elfcpp::Elf_types<64>::Elf_Swxword val)
  { p->put_r_addend(val); }
};

// Forward declaration.
static unsigned int
mips_get_size_for_reloc(unsigned int, Relobj*);

// A class for inquiring about properties of a relocation,
// used while scanning relocs during a relocatable link and
// garbage collection.

template<int sh_type_, int size, bool big_endian>
class Mips_classify_reloc;

template<int sh_type_, bool big_endian>
class Mips_classify_reloc<sh_type_, 32, big_endian> :
    public gold::Default_classify_reloc<sh_type_, 32, big_endian>
{
 public:
  typedef typename Mips_reloc_types<sh_type_, 32, big_endian>::Reloc
      Reltype;
  typedef typename Mips_reloc_types<sh_type_, 32, big_endian>::Reloc_write
      Reltype_write;

  // Return the symbol referred to by the relocation.
  static inline unsigned int
  get_r_sym(const Reltype* reloc)
  { return elfcpp::elf_r_sym<32>(reloc->get_r_info()); }

  // Return the type of the relocation.
  static inline unsigned int
  get_r_type(const Reltype* reloc)
  { return elfcpp::elf_r_type<32>(reloc->get_r_info()); }

  static inline unsigned int
  get_r_type2(const Reltype*)
  { return 0; }

  static inline unsigned int
  get_r_type3(const Reltype*)
  { return 0; }

  static inline unsigned int
  get_r_ssym(const Reltype*)
  { return 0; }

  // Return the explicit addend of the relocation (return 0 for SHT_REL).
  static inline unsigned int
  get_r_addend(const Reltype* reloc)
  {
    if (sh_type_ == elfcpp::SHT_REL)
      return 0;
    return Mips_reloc_types<sh_type_, 32, big_endian>::get_r_addend(reloc);
  }

  // Write the r_info field to a new reloc, using the r_info field from
  // the original reloc, replacing the r_sym field with R_SYM.
  static inline void
  put_r_info(Reltype_write* new_reloc, Reltype* reloc, unsigned int r_sym)
  {
    unsigned int r_type = elfcpp::elf_r_type<32>(reloc->get_r_info());
    new_reloc->put_r_info(elfcpp::elf_r_info<32>(r_sym, r_type));
  }

  // Write the r_addend field to a new reloc.
  static inline void
  put_r_addend(Reltype_write* to,
	       typename elfcpp::Elf_types<32>::Elf_Swxword addend)
  { Mips_reloc_types<sh_type_, 32, big_endian>::set_reloc_addend(to, addend); }

  // Return the size of the addend of the relocation (only used for SHT_REL).
  static unsigned int
  get_size_for_reloc(unsigned int r_type, Relobj* obj)
  { return mips_get_size_for_reloc(r_type, obj); }
};

template<int sh_type_, bool big_endian>
class Mips_classify_reloc<sh_type_, 64, big_endian> :
    public gold::Default_classify_reloc<sh_type_, 64, big_endian>
{
 public:
  typedef typename Mips_reloc_types<sh_type_, 64, big_endian>::Reloc
      Reltype;
  typedef typename Mips_reloc_types<sh_type_, 64, big_endian>::Reloc_write
      Reltype_write;

  // Return the symbol referred to by the relocation.
  static inline unsigned int
  get_r_sym(const Reltype* reloc)
  { return reloc->get_r_sym(); }

  // Return the r_type of the relocation.
  static inline unsigned int
  get_r_type(const Reltype* reloc)
  { return reloc->get_r_type(); }

  // Return the r_type2 of the relocation.
  static inline unsigned int
  get_r_type2(const Reltype* reloc)
  { return reloc->get_r_type2(); }

  // Return the r_type3 of the relocation.
  static inline unsigned int
  get_r_type3(const Reltype* reloc)
  { return reloc->get_r_type3(); }

  // Return the special symbol of the relocation.
  static inline unsigned int
  get_r_ssym(const Reltype* reloc)
  { return reloc->get_r_ssym(); }

  // Return the explicit addend of the relocation (return 0 for SHT_REL).
  static inline typename elfcpp::Elf_types<64>::Elf_Swxword
  get_r_addend(const Reltype* reloc)
  {
    if (sh_type_ == elfcpp::SHT_REL)
      return 0;
    return Mips_reloc_types<sh_type_, 64, big_endian>::get_r_addend(reloc);
  }

  // Write the r_info field to a new reloc, using the r_info field from
  // the original reloc, replacing the r_sym field with R_SYM.
  static inline void
  put_r_info(Reltype_write* new_reloc, Reltype* reloc, unsigned int r_sym)
  {
    new_reloc->put_r_sym(r_sym);
    new_reloc->put_r_ssym(reloc->get_r_ssym());
    new_reloc->put_r_type3(reloc->get_r_type3());
    new_reloc->put_r_type2(reloc->get_r_type2());
    new_reloc->put_r_type(reloc->get_r_type());
  }

  // Write the r_addend field to a new reloc.
  static inline void
  put_r_addend(Reltype_write* to,
	       typename elfcpp::Elf_types<64>::Elf_Swxword addend)
  { Mips_reloc_types<sh_type_, 64, big_endian>::set_reloc_addend(to, addend); }

  // Return the size of the addend of the relocation (only used for SHT_REL).
  static unsigned int
  get_size_for_reloc(unsigned int r_type, Relobj* obj)
  { return mips_get_size_for_reloc(r_type, obj); }
};

template<int size, bool big_endian>
class Target_mips : public Sized_target<size, big_endian>
{
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address;
  typedef Mips_output_data_reloc<elfcpp::SHT_REL, true, size, big_endian>
    Reloc_section;
  typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype32;
  typedef typename elfcpp::Swap<size, big_endian>::Valtype Valtype;
  typedef typename Mips_reloc_types<elfcpp::SHT_REL, size, big_endian>::Reloc
      Reltype;
  typedef typename Mips_reloc_types<elfcpp::SHT_RELA, size, big_endian>::Reloc
      Relatype;

 public:
  Target_mips(const Target::Target_info* info = &mips_info)
    : Sized_target<size, big_endian>(info), got_(NULL), gp_(NULL), plt_(NULL),
      got_plt_(NULL), rel_dyn_(NULL), rld_map_(NULL), copy_relocs_(),
      dyn_relocs_(), la25_stub_(NULL), mips_mach_extensions_(),
      mips_stubs_(NULL), attributes_section_data_(NULL), abiflags_(NULL),
      mach_(0), layout_(NULL), got16_addends_(), has_abiflags_section_(false),
      entry_symbol_is_compressed_(false), insn32_(false)
  {
    this->add_machine_extensions();
  }

  // The offset of $gp from the beginning of the .got section.
  static const unsigned int MIPS_GP_OFFSET = 0x7ff0;

  // The maximum size of the GOT for it to be addressable using 16-bit
  // offsets from $gp.
  static const unsigned int MIPS_GOT_MAX_SIZE = MIPS_GP_OFFSET + 0x7fff;

  // Make a new symbol table entry for the Mips target.
  Sized_symbol<size>*
  make_symbol(const char*, elfcpp::STT, Object*, unsigned int, uint64_t)
  { return new Mips_symbol<size>(); }

  // Process the relocations to determine unreferenced sections for
  // garbage collection.
  void
  gc_process_relocs(Symbol_table* symtab,
                    Layout* layout,
                    Sized_relobj_file<size, big_endian>* object,
                    unsigned int data_shndx,
                    unsigned int sh_type,
                    const unsigned char* prelocs,
                    size_t reloc_count,
                    Output_section* output_section,
                    bool needs_special_offset_handling,
                    size_t local_symbol_count,
                    const unsigned char* plocal_symbols);

  // Scan the relocations to look for symbol adjustments.
  void
  scan_relocs(Symbol_table* symtab,
              Layout* layout,
              Sized_relobj_file<size, big_endian>* object,
              unsigned int data_shndx,
              unsigned int sh_type,
              const unsigned char* prelocs,
              size_t reloc_count,
              Output_section* output_section,
              bool needs_special_offset_handling,
              size_t local_symbol_count,
              const unsigned char* plocal_symbols);

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

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

  // Scan the relocs during a relocatable link.
  void
  scan_relocatable_relocs(Symbol_table* symtab,
                          Layout* layout,
                          Sized_relobj_file<size, big_endian>* object,
                          unsigned int data_shndx,
                          unsigned int sh_type,
                          const unsigned char* prelocs,
                          size_t reloc_count,
                          Output_section* output_section,
                          bool needs_special_offset_handling,
                          size_t local_symbol_count,
                          const unsigned char* plocal_symbols,
                          Relocatable_relocs*);

  // Scan the relocs for --emit-relocs.
  void
  emit_relocs_scan(Symbol_table* symtab,
		   Layout* layout,
		   Sized_relobj_file<size, big_endian>* object,
		   unsigned int data_shndx,
		   unsigned int sh_type,
		   const unsigned char* prelocs,
		   size_t reloc_count,
		   Output_section* output_section,
		   bool needs_special_offset_handling,
		   size_t local_symbol_count,
		   const unsigned char* plocal_syms,
		   Relocatable_relocs* rr);

  // Emit relocations for a section.
  void
  relocate_relocs(const Relocate_info<size, big_endian>*,
                  unsigned int sh_type,
                  const unsigned char* prelocs,
                  size_t reloc_count,
                  Output_section* output_section,
                  typename elfcpp::Elf_types<size>::Elf_Off
                    offset_in_output_section,
                  unsigned char* view,
                  Mips_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<size, big_endian>* relinfo,
                               unsigned int sh_type,
                               const unsigned char* preloc_in,
                               size_t relnum,
                               Output_section* output_section,
                               typename elfcpp::Elf_types<size>::Elf_Off
                                 offset_in_output_section,
                               unsigned char* view,
                               Mips_address view_address,
                               section_size_type view_size,
                               unsigned char* preloc_out);

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

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

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

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

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

  // Get the GOT section.
  Mips_output_data_got<size, big_endian>*
  got_section() const
  {
    gold_assert(this->got_ != NULL);
    return this->got_;
  }

  // Get the .MIPS.stubs section, creating it if necessary.
  Mips_output_data_mips_stubs<size, big_endian>*
  mips_stubs_section(Layout* layout);

  // Get the .MIPS.stubs section.
  Mips_output_data_mips_stubs<size, big_endian>*
  mips_stubs_section() const
  {
    gold_assert(this->mips_stubs_ != NULL);
    return this->mips_stubs_;
  }

  // Get the LA25 stub section, creating it if necessary.
  Mips_output_data_la25_stub<size, big_endian>*
  la25_stub_section(Layout*);

  // Get the LA25 stub section.
  Mips_output_data_la25_stub<size, big_endian>*
  la25_stub_section()
  {
    gold_assert(this->la25_stub_ != NULL);
    return this->la25_stub_;
  }

  // Get gp value.  It has the value of .got + 0x7FF0.
  Mips_address
  gp_value() const
  {
    if (this->gp_ != NULL)
      return this->gp_->value();
    return 0;
  }

  // Get gp value.  It has the value of .got + 0x7FF0.  Adjust it for
  // multi-GOT links so that OBJECT's GOT + 0x7FF0 is returned.
  Mips_address
  adjusted_gp_value(const Mips_relobj<size, big_endian>* object)
  {
    if (this->gp_ == NULL)
      return 0;

    bool multi_got = false;
    if (this->has_got_section())
      multi_got = this->got_section()->multi_got();
    if (!multi_got)
      return this->gp_->value();
    else
      return this->gp_->value() + this->got_section()->get_got_offset(object);
  }

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

  bool
  do_has_custom_set_dynsym_indexes() const
  { return true; }

  // Don't emit input .reginfo/.MIPS.abiflags sections to
  // output .reginfo/.MIPS.abiflags.
  bool
  do_should_include_section(elfcpp::Elf_Word sh_type) const
  {
    return ((sh_type != elfcpp::SHT_MIPS_REGINFO)
             && (sh_type != elfcpp::SHT_MIPS_ABIFLAGS));
  }

  // Set the dynamic symbol indexes.  INDEX is the index of the first
  // global dynamic symbol.  Pointers to the symbols are stored into the
  // vector SYMS.  The names are added to DYNPOOL.  This returns an
  // updated dynamic symbol index.
  unsigned int
  do_set_dynsym_indexes(std::vector<Symbol*>* dyn_symbols, unsigned int index,
                        std::vector<Symbol*>* syms, Stringpool* dynpool,
                        Versions* versions, Symbol_table* symtab) const;

  // Remove .MIPS.stubs entry for a symbol.
  void
  remove_lazy_stub_entry(Mips_symbol<size>* sym)
  {
    if (this->mips_stubs_ != NULL)
      this->mips_stubs_->remove_entry(sym);
  }

  // The value to write into got[1] for SVR4 targets, to identify it is
  // a GNU object.  The dynamic linker can then use got[1] to store the
  // module pointer.
  uint64_t
  mips_elf_gnu_got1_mask()
  {
    if (this->is_output_n64())
      return (uint64_t)1 << 63;
    else
      return 1 << 31;
  }

  // Whether the output has microMIPS code.  This is valid only after
  // merge_obj_e_flags() is called.
  bool
  is_output_micromips() const
  {
    gold_assert(this->are_processor_specific_flags_set());
    return elfcpp::is_micromips(this->processor_specific_flags());
  }

  // Whether the output uses N32 ABI.  This is valid only after
  // merge_obj_e_flags() is called.
  bool
  is_output_n32() const
  {
    gold_assert(this->are_processor_specific_flags_set());
    return elfcpp::abi_n32(this->processor_specific_flags());
  }

  // Whether the output uses R6 ISA.  This is valid only after
  // merge_obj_e_flags() is called.
  bool
  is_output_r6() const
  {
    gold_assert(this->are_processor_specific_flags_set());
    return elfcpp::r6_isa(this->processor_specific_flags());
  }

  // Whether the output uses N64 ABI.
  bool
  is_output_n64() const
  { return size == 64; }

  // Whether the output uses NEWABI.  This is valid only after
  // merge_obj_e_flags() is called.
  bool
  is_output_newabi() const
  { return this->is_output_n32() || this->is_output_n64(); }

  // Whether we can only use 32-bit microMIPS instructions.
  bool
  use_32bit_micromips_instructions() const
  { return this->insn32_; }

  // Return the r_sym field from a relocation.
  unsigned int
  get_r_sym(const unsigned char* preloc) const
  {
    // Since REL and RELA relocs share the same structure through
    // the r_info field, we can just use REL here.
    Reltype rel(preloc);
    return Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>::
	get_r_sym(&rel);
  }

 protected:
  // 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.
  uint64_t
  do_dynsym_value(const Symbol* gsym) const;

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

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

  // Make an output section.
  Output_section*
  do_make_output_section(const char* name, elfcpp::Elf_Word type,
                         elfcpp::Elf_Xword flags)
    {
      if (type == elfcpp::SHT_MIPS_OPTIONS)
        return new Mips_output_section_options<size, big_endian>(name, type,
                                                                 flags, this);
      else
        return new Output_section(name, type, flags);
    }

  // Adjust ELF file header.
  void
  do_adjust_elf_header(unsigned char* view, int len);

  // Get the custom dynamic tag value.
  unsigned int
  do_dynamic_tag_custom_value(elfcpp::DT) const;

  // Adjust the value written to the dynamic symbol table.
  virtual void
  do_adjust_dyn_symbol(const Symbol* sym, unsigned char* view) const
  {
    elfcpp::Sym<size, big_endian> isym(view);
    elfcpp::Sym_write<size, big_endian> osym(view);
    const Mips_symbol<size>* mips_sym = Mips_symbol<size>::as_mips_sym(sym);

    // Keep dynamic compressed symbols odd.  This allows the dynamic linker
    // to treat compressed symbols like any other.
    Mips_address value = isym.get_st_value();
    if (mips_sym->is_mips16() && value != 0)
      {
        if (!mips_sym->has_mips16_fn_stub())
          value |= 1;
        else
          {
            // If we have a MIPS16 function with a stub, the dynamic symbol
            // must refer to the stub, since only the stub uses the standard
            // calling conventions.  Stub contains MIPS32 code, so don't add +1
            // in this case.

            // There is a code which does this in the method
            // Target_mips::do_dynsym_value, but that code will only be
            // executed if the symbol is from dynobj.
            // TODO(sasa): GNU ld also changes the value in non-dynamic symbol
            // table.

            Mips16_stub_section<size, big_endian>* fn_stub =
              mips_sym->template get_mips16_fn_stub<big_endian>();
            value = fn_stub->output_address();
            osym.put_st_size(fn_stub->section_size());
          }

        osym.put_st_value(value);
        osym.put_st_other(elfcpp::elf_st_other(sym->visibility(),
                          mips_sym->nonvis() - (elfcpp::STO_MIPS16 >> 2)));
      }
    else if ((mips_sym->is_micromips()
              // Stubs are always microMIPS if there is any microMIPS code in
              // the output.
              || (this->is_output_micromips() && mips_sym->has_lazy_stub()))
             && value != 0)
      {
        osym.put_st_value(value | 1);
        osym.put_st_other(elfcpp::elf_st_other(sym->visibility(),
                          mips_sym->nonvis() - (elfcpp::STO_MICROMIPS >> 2)));
      }
  }

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

    static inline int
    get_reference_flags(unsigned int r_type);

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

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

    inline void
    local(Symbol_table* symtab, Layout* layout, Target_mips* target,
          Sized_relobj_file<size, big_endian>* object,
          unsigned int data_shndx,
          Output_section* output_section,
          const Relatype* rela,
          const Reltype* rel,
          unsigned int rel_type,
          unsigned int r_type,
          const elfcpp::Sym<size, big_endian>& lsym,
          bool is_discarded);

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

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

    inline void
    global(Symbol_table* symtab, Layout* layout, Target_mips* target,
           Sized_relobj_file<size, big_endian>* object,
           unsigned int data_shndx,
           Output_section* output_section,
           const Relatype* rela,
           const Reltype* rel,
           unsigned int rel_type,
           unsigned int r_type,
           Symbol* gsym);

    inline bool
    local_reloc_may_be_function_pointer(Symbol_table* , Layout*,
                                        Target_mips*,
                                        Sized_relobj_file<size, big_endian>*,
                                        unsigned int,
                                        Output_section*,
                                        const Reltype&,
                                        unsigned int,
                                        const elfcpp::Sym<size, big_endian>&)
    { return false; }

    inline bool
    global_reloc_may_be_function_pointer(Symbol_table*, Layout*,
                                         Target_mips*,
                                         Sized_relobj_file<size, big_endian>*,
                                         unsigned int,
                                         Output_section*,
                                         const Reltype&,
                                         unsigned int, Symbol*)
    { return false; }

    inline bool
    local_reloc_may_be_function_pointer(Symbol_table*, Layout*,
                                        Target_mips*,
                                        Sized_relobj_file<size, big_endian>*,
                                        unsigned int,
                                        Output_section*,
                                        const Relatype&,
                                        unsigned int,
                                        const elfcpp::Sym<size, big_endian>&)
    { return false; }

    inline bool
    global_reloc_may_be_function_pointer(Symbol_table*, Layout*,
                                         Target_mips*,
                                         Sized_relobj_file<size, big_endian>*,
                                         unsigned int,
                                         Output_section*,
                                         const Relatype&,
                                         unsigned int, Symbol*)
    { return false; }
   private:
    static void
    unsupported_reloc_local(Sized_relobj_file<size, big_endian>*,
                            unsigned int r_type);

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

  // The class which implements relocation.
  class Relocate
  {
   public:
    Relocate()
      : calculated_value_(0), calculate_only_(false)
    { }

    ~Relocate()
    { }

    // Return whether a R_MIPS_32/R_MIPS_64 relocation needs to be applied.
    inline bool
    should_apply_static_reloc(const Mips_symbol<size>* gsym,
                              unsigned int r_type,
                              Output_section* output_section,
                              Target_mips* target);

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

   private:
    // Result of the relocation.
    Valtype calculated_value_;
    // Whether we have to calculate relocation instead of applying it.
    bool calculate_only_;
  };

  // This POD class holds the dynamic relocations that should be emitted instead
  // of R_MIPS_32, R_MIPS_REL32 and R_MIPS_64 relocations.  We will emit these
  // relocations if it turns out that the symbol does not have static
  // relocations.
  class Dyn_reloc
  {
   public:
    Dyn_reloc(Mips_symbol<size>* sym, unsigned int r_type,
              Mips_relobj<size, big_endian>* relobj, unsigned int shndx,
              Output_section* output_section, Mips_address r_offset)
      : sym_(sym), r_type_(r_type), relobj_(relobj),
        shndx_(shndx), output_section_(output_section),
        r_offset_(r_offset)
    { }

    // Emit this reloc if appropriate.  This is called after we have
    // scanned all the relocations, so we know whether the symbol has
    // static relocations.
    void
    emit(Reloc_section* rel_dyn, Mips_output_data_got<size, big_endian>* got,
         Symbol_table* symtab)
    {
      if (!this->sym_->has_static_relocs())
        {
          got->record_global_got_symbol(this->sym_, this->relobj_,
                                        this->r_type_, true, false);
          if (!symbol_references_local(this->sym_,
                                this->sym_->should_add_dynsym_entry(symtab)))
            rel_dyn->add_global(this->sym_, this->r_type_,
                                this->output_section_, this->relobj_,
                                this->shndx_, this->r_offset_);
          else
            rel_dyn->add_symbolless_global_addend(this->sym_, this->r_type_,
                                          this->output_section_, this->relobj_,
                                          this->shndx_, this->r_offset_);
        }
    }

   private:
    Mips_symbol<size>* sym_;
    unsigned int r_type_;
    Mips_relobj<size, big_endian>* relobj_;
    unsigned int shndx_;
    Output_section* output_section_;
    Mips_address r_offset_;
  };

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

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

  // Check whether the given ELF header flags describe a 32-bit binary.
  bool
  mips_32bit_flags(elfcpp::Elf_Word);

  enum Mips_mach {
    mach_mips3000             = 3000,
    mach_mips3900             = 3900,
    mach_mips4000             = 4000,
    mach_mips4010             = 4010,
    mach_mips4100             = 4100,
    mach_mips4111             = 4111,
    mach_mips4120             = 4120,
    mach_mips4300             = 4300,
    mach_mips4400             = 4400,
    mach_mips4600             = 4600,
    mach_mips4650             = 4650,
    mach_mips5000             = 5000,
    mach_mips5400             = 5400,
    mach_mips5500             = 5500,
    mach_mips5900             = 5900,
    mach_mips6000             = 6000,
    mach_mips7000             = 7000,
    mach_mips8000             = 8000,
    mach_mips9000             = 9000,
    mach_mips10000            = 10000,
    mach_mips12000            = 12000,
    mach_mips14000            = 14000,
    mach_mips16000            = 16000,
    mach_mips16               = 16,
    mach_mips5                = 5,
    mach_mips_loongson_2e     = 3001,
    mach_mips_loongson_2f     = 3002,
    mach_mips_loongson_3a     = 3003,
    mach_mips_sb1             = 12310201, // octal 'SB', 01
    mach_mips_octeon          = 6501,
    mach_mips_octeonp         = 6601,
    mach_mips_octeon2         = 6502,
    mach_mips_octeon3         = 6503,
    mach_mips_xlr             = 887682,   // decimal 'XLR'
    mach_mipsisa32            = 32,
    mach_mipsisa32r2          = 33,
    mach_mipsisa32r3          = 34,
    mach_mipsisa32r5          = 36,
    mach_mipsisa32r6          = 37,
    mach_mipsisa64            = 64,
    mach_mipsisa64r2          = 65,
    mach_mipsisa64r3          = 66,
    mach_mipsisa64r5          = 68,
    mach_mipsisa64r6          = 69,
    mach_mips_micromips       = 96
  };

  // Return the MACH for a MIPS e_flags value.
  unsigned int
  elf_mips_mach(elfcpp::Elf_Word);

  // Return the MACH for each .MIPS.abiflags ISA Extension.
  unsigned int
  mips_isa_ext_mach(unsigned int);

  // Return the .MIPS.abiflags value representing each ISA Extension.
  unsigned int
  mips_isa_ext(unsigned int);

  // Update the isa_level, isa_rev, isa_ext fields of abiflags.
  void
  update_abiflags_isa(const std::string&, elfcpp::Elf_Word,
                      Mips_abiflags<big_endian>*);

  // Infer the content of the ABI flags based on the elf header.
  void
  infer_abiflags(Mips_relobj<size, big_endian>*, Mips_abiflags<big_endian>*);

  // Create abiflags from elf header or from .MIPS.abiflags section.
  void
  create_abiflags(Mips_relobj<size, big_endian>*, Mips_abiflags<big_endian>*);

  // Return the meaning of fp_abi, or "unknown" if not known.
  const char*
  fp_abi_string(int);

  // Select fp_abi.
  int
  select_fp_abi(const std::string&, int, int);

  // Merge attributes from input object.
  void
  merge_obj_attributes(const std::string&, const Attributes_section_data*);

  // Merge abiflags from input object.
  void
  merge_obj_abiflags(const std::string&, Mips_abiflags<big_endian>*);

  // Check whether machine EXTENSION is an extension of machine BASE.
  bool
  mips_mach_extends(unsigned int, unsigned int);

  // Merge file header flags from input object.
  void
  merge_obj_e_flags(const std::string&, elfcpp::Elf_Word);

  // Encode ISA level and revision as a single value.
  int
  level_rev(unsigned char isa_level, unsigned char isa_rev) const
  { return (isa_level << 3) | isa_rev; }

  // True if we are linking for CPUs that are faster if JAL is converted to BAL.
  static inline bool
  jal_to_bal()
  { return false; }

  // True if we are linking for CPUs that are faster if JALR is converted to
  // BAL.  This should be safe for all architectures.  We enable this predicate
  // for all CPUs.
  static inline bool
  jalr_to_bal()
  { return true; }

  // True if we are linking for CPUs that are faster if JR is converted to B.
  // This should be safe for all architectures.  We enable this predicate for
  // all CPUs.
  static inline bool
  jr_to_b()
  { return true; }

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

  // Create a PLT entry for a global symbol referenced by r_type relocation.
  void
  make_plt_entry(Symbol_table*, Layout*, Mips_symbol<size>*,
                 unsigned int r_type);

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

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

  // Copy a relocation against a global symbol.
  void
  copy_reloc(Symbol_table* symtab, Layout* layout,
             Sized_relobj_file<size, big_endian>* object,
             unsigned int shndx, Output_section* output_section,
             Symbol* sym, unsigned int r_type, Mips_address r_offset)
  {
    this->copy_relocs_.copy_reloc(symtab, layout,
                                  symtab->get_sized_symbol<size>(sym),
                                  object, shndx, output_section,
                                  r_type, r_offset, 0,
                                  this->rel_dyn_section(layout));
  }

  void
  dynamic_reloc(Mips_symbol<size>* sym, unsigned int r_type,
                Mips_relobj<size, big_endian>* relobj,
                unsigned int shndx, Output_section* output_section,
                Mips_address r_offset)
  {
    this->dyn_relocs_.push_back(Dyn_reloc(sym, r_type, relobj, shndx,
                                          output_section, r_offset));
  }

  // Calculate value of _gp symbol.
  void
  set_gp(Layout*, Symbol_table*);

  const char*
  elf_mips_abi_name(elfcpp::Elf_Word e_flags);
  const char*
  elf_mips_mach_name(elfcpp::Elf_Word e_flags);

  // Adds entries that describe how machines relate to one another.  The entries
  // are ordered topologically with MIPS I extensions listed last.  First
  // element is extension, second element is base.
  void
  add_machine_extensions()
  {
    // MIPS64r2 extensions.
    this->add_extension(mach_mips_octeon3, mach_mips_octeon2);
    this->add_extension(mach_mips_octeon2, mach_mips_octeonp);
    this->add_extension(mach_mips_octeonp, mach_mips_octeon);
    this->add_extension(mach_mips_octeon, mach_mipsisa64r2);
    this->add_extension(mach_mips_loongson_3a, mach_mipsisa64r2);

    // MIPS64 extensions.
    this->add_extension(mach_mipsisa64r2, mach_mipsisa64);
    this->add_extension(mach_mips_sb1, mach_mipsisa64);
    this->add_extension(mach_mips_xlr, mach_mipsisa64);

    // MIPS V extensions.
    this->add_extension(mach_mipsisa64, mach_mips5);

    // R10000 extensions.
    this->add_extension(mach_mips12000, mach_mips10000);
    this->add_extension(mach_mips14000, mach_mips10000);
    this->add_extension(mach_mips16000, mach_mips10000);

    // R5000 extensions.  Note: the vr5500 ISA is an extension of the core
    // vr5400 ISA, but doesn't include the multimedia stuff.  It seems
    // better to allow vr5400 and vr5500 code to be merged anyway, since
    // many libraries will just use the core ISA.  Perhaps we could add
    // some sort of ASE flag if this ever proves a problem.
    this->add_extension(mach_mips5500, mach_mips5400);
    this->add_extension(mach_mips5400, mach_mips5000);

    // MIPS IV extensions.
    this->add_extension(mach_mips5, mach_mips8000);
    this->add_extension(mach_mips10000, mach_mips8000);
    this->add_extension(mach_mips5000, mach_mips8000);
    this->add_extension(mach_mips7000, mach_mips8000);
    this->add_extension(mach_mips9000, mach_mips8000);

    // VR4100 extensions.
    this->add_extension(mach_mips4120, mach_mips4100);
    this->add_extension(mach_mips4111, mach_mips4100);

    // MIPS III extensions.
    this->add_extension(mach_mips_loongson_2e, mach_mips4000);
    this->add_extension(mach_mips_loongson_2f, mach_mips4000);
    this->add_extension(mach_mips8000, mach_mips4000);
    this->add_extension(mach_mips4650, mach_mips4000);
    this->add_extension(mach_mips4600, mach_mips4000);
    this->add_extension(mach_mips4400, mach_mips4000);
    this->add_extension(mach_mips4300, mach_mips4000);
    this->add_extension(mach_mips4100, mach_mips4000);
    this->add_extension(mach_mips4010, mach_mips4000);
    this->add_extension(mach_mips5900, mach_mips4000);

    // MIPS32 extensions.
    this->add_extension(mach_mipsisa32r2, mach_mipsisa32);

    // MIPS II extensions.
    this->add_extension(mach_mips4000, mach_mips6000);
    this->add_extension(mach_mipsisa32, mach_mips6000);

    // MIPS I extensions.
    this->add_extension(mach_mips6000, mach_mips3000);
    this->add_extension(mach_mips3900, mach_mips3000);
  }

  // Add value to MIPS extenstions.
  void
  add_extension(unsigned int base, unsigned int extension)
  {
    std::pair<unsigned int, unsigned int> ext(base, extension);
    this->mips_mach_extensions_.push_back(ext);
  }

  // Return the number of entries in the .dynsym section.
  unsigned int get_dt_mips_symtabno() const
  {
    return ((unsigned int)(this->layout_->dynsym_section()->data_size()
                           / elfcpp::Elf_sizes<size>::sym_size));
    // TODO(sasa): Entry size is MIPS_ELF_SYM_SIZE.
  }

  // Information about this specific target which we pass to the
  // general Target structure.
  static const Target::Target_info mips_info;
  // The GOT section.
  Mips_output_data_got<size, big_endian>* got_;
  // gp symbol.  It has the value of .got + 0x7FF0.
  Sized_symbol<size>* gp_;
  // The PLT section.
  Mips_output_data_plt<size, big_endian>* plt_;
  // The GOT PLT section.
  Output_data_space* got_plt_;
  // The dynamic reloc section.
  Reloc_section* rel_dyn_;
  // The .rld_map section.
  Output_data_zero_fill* rld_map_;
  // Relocs saved to avoid a COPY reloc.
  Mips_copy_relocs<elfcpp::SHT_REL, size, big_endian> copy_relocs_;

  // A list of dyn relocs to be saved.
  std::vector<Dyn_reloc> dyn_relocs_;

  // The LA25 stub section.
  Mips_output_data_la25_stub<size, big_endian>* la25_stub_;
  // Architecture extensions.
  std::vector<std::pair<unsigned int, unsigned int> > mips_mach_extensions_;
  // .MIPS.stubs
  Mips_output_data_mips_stubs<size, big_endian>* mips_stubs_;

  // Attributes section data in output.
  Attributes_section_data* attributes_section_data_;
  // .MIPS.abiflags section data in output.
  Mips_abiflags<big_endian>* abiflags_;

  unsigned int mach_;
  Layout* layout_;

  typename std::list<got16_addend<size, big_endian> > got16_addends_;

  // Whether there is an input .MIPS.abiflags section.
  bool has_abiflags_section_;

  // Whether the entry symbol is mips16 or micromips.
  bool entry_symbol_is_compressed_;

  // Whether we can use only 32-bit microMIPS instructions.
  // TODO(sasa): This should be a linker option.
  bool insn32_;
};

// Helper structure for R_MIPS*_HI16/LO16 and R_MIPS*_GOT16/LO16 relocations.
// It records high part of the relocation pair.

template<int size, bool big_endian>
struct reloc_high
{
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address;

  reloc_high(unsigned char* _view, const Mips_relobj<size, big_endian>* _object,
             const Symbol_value<size>* _psymval, Mips_address _addend,
             unsigned int _r_type, unsigned int _r_sym, bool _extract_addend,
             Mips_address _address = 0, bool _gp_disp = false)
    : view(_view), object(_object), psymval(_psymval), addend(_addend),
      r_type(_r_type), r_sym(_r_sym), extract_addend(_extract_addend),
      address(_address), gp_disp(_gp_disp)
  { }

  unsigned char* view;
  const Mips_relobj<size, big_endian>* object;
  const Symbol_value<size>* psymval;
  Mips_address addend;
  unsigned int r_type;
  unsigned int r_sym;
  bool extract_addend;
  Mips_address address;
  bool gp_disp;
};

template<int size, bool big_endian>
class Mips_relocate_functions : public Relocate_functions<size, big_endian>
{
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Mips_address;
  typedef typename elfcpp::Swap<size, big_endian>::Valtype Valtype;
  typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype16;
  typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype32;
  typedef typename elfcpp::Swap<64, big_endian>::Valtype Valtype64;

 public:
  typedef enum
  {
    STATUS_OKAY,            // No error during relocation.
    STATUS_OVERFLOW,        // Relocation overflow.
    STATUS_BAD_RELOC,       // Relocation cannot be applied.
    STATUS_PCREL_UNALIGNED  // Unaligned PC-relative relocation.
  } Status;

 private:
  typedef Relocate_functions<size, big_endian> Base;
  typedef Mips_relocate_functions<size, big_endian> This;

  static typename std::list<reloc_high<size, big_endian> > hi16_relocs;
  static typename std::list<reloc_high<size, big_endian> > got16_relocs;
  static typename std::list<reloc_high<size, big_endian> > pchi16_relocs;

  template<int valsize>
  static inline typename This::Status
  check_overflow(Valtype value)
  {
    if (size == 32)
      return (Bits<valsize>::has_overflow32(value)
              ? This::STATUS_OVERFLOW
              : This::STATUS_OKAY);

    return (Bits<valsize>::has_overflow(value)
            ? This::STATUS_OVERFLOW
            : This::STATUS_OKAY);
  }

  static inline bool
  should_shuffle_micromips_reloc(unsigned int r_type)
  {
    return (micromips_reloc(r_type)
            && r_type != elfcpp::R_MICROMIPS_PC7_S1
            && r_type != elfcpp::R_MICROMIPS_PC10_S1);
  }

 public:
  //   R_MIPS16_26 is used for the mips16 jal and jalx instructions.
  //   Most mips16 instructions are 16 bits, but these instructions
  //   are 32 bits.
  //
  //   The format of these instructions is:
  //
  //   +--------------+--------------------------------+
  //   |     JALX     | X|   Imm 20:16  |   Imm 25:21  |
  //   +--------------+--------------------------------+
  //   |                Immediate  15:0                |
  //   +-----------------------------------------------+
  //
  //   JALX is the 5-bit value 00011.  X is 0 for jal, 1 for jalx.
  //   Note that the immediate value in the first word is swapped.
  //
  //   When producing a relocatable object file, R_MIPS16_26 is
  //   handled mostly like R_MIPS_26.  In particular, the addend is
  //   stored as a straight 26-bit value in a 32-bit instruction.
  //   (gas makes life simpler for itself by never adjusting a
  //   R_MIPS16_26 reloc to be against a section, so the addend is
  //   always zero).  However, the 32 bit instruction is stored as 2
  //   16-bit values, rather than a single 32-bit value.  In a
  //   big-endian file, the result is the same; in a little-endian
  //   file, the two 16-bit halves of the 32 bit value are swapped.
  //   This is so that a disassembler can recognize the jal
  //   instruction.
  //
  //   When doing a final link, R_MIPS16_26 is treated as a 32 bit
  //   instruction stored as two 16-bit values.  The addend A is the
  //   contents of the targ26 field.  The calculation is the same as
  //   R_MIPS_26.  When storing the calculated value, reorder the
  //   immediate value as shown above, and don't forget to store the
  //   value as two 16-bit values.
  //
  //   To put it in MIPS ABI terms, the relocation field is T-targ26-16,
  //   defined as
  //
  //   big-endian:
  //   +--------+----------------------+
  //   |        |                      |
  //   |        |    targ26-16         |
  //   |31    26|25                   0|
  //   +--------+----------------------+
  //
  //   little-endian:
  //   +----------+------+-------------+
  //   |          |      |             |
  //   |  sub1    |      |     sub2    |
  //   |0        9|10  15|16         31|
  //   +----------+--------------------+
  //   where targ26-16 is sub1 followed by sub2 (i.e., the addend field A is
  //   ((sub1 << 16) | sub2)).
  //
  //   When producing a relocatable object file, the calculation is
  //   (((A < 2) | ((P + 4) & 0xf0000000) + S) >> 2)
  //   When producing a fully linked file, the calculation is
  //   let R = (((A < 2) | ((P + 4) & 0xf0000000) + S) >> 2)
  //   ((R & 0x1f0000) << 5) | ((R & 0x3e00000) >> 5) | (R & 0xffff)
  //
  //   The table below lists the other MIPS16 instruction relocations.
  //   Each one is calculated in the same way as the non-MIPS16 relocation
  //   given on the right, but using the extended MIPS16 layout of 16-bit
  //   immediate fields:
  //
  //      R_MIPS16_GPREL          R_MIPS_GPREL16
  //      R_MIPS16_GOT16          R_MIPS_GOT16
  //      R_MIPS16_CALL16         R_MIPS_CALL16
  //      R_MIPS16_HI16           R_MIPS_HI16
  //      R_MIPS16_LO16           R_MIPS_LO16
  //
  //   A typical instruction will have a format like this:
  //
  //   +--------------+--------------------------------+
  //   |    EXTEND    |     Imm 10:5    |   Imm 15:11  |
  //   +--------------+--------------------------------+
  //   |    Major     |   rx   |   ry   |   Imm  4:0   |
  //   +--------------+--------------------------------+
  //
  //   EXTEND is the five bit value 11110.  Major is the instruction
  //   opcode.
  //
  //   All we need to do here is shuffle the bits appropriately.
  //   As above, the two 16-bit halves must be swapped on a
  //   little-endian system.

  // Similar to MIPS16, the two 16-bit halves in microMIPS must be swapped
  // on a little-endian system.  This does not apply to R_MICROMIPS_PC7_S1
  // and R_MICROMIPS_PC10_S1 relocs that apply to 16-bit instructions.

  static void
  mips_reloc_unshuffle(unsigned char* view, unsigned int r_type,
                       bool jal_shuffle)
  {
    if (!mips16_reloc(r_type)
        && !should_shuffle_micromips_reloc(r_type))
      return;

    // Pick up the first and second halfwords of the instruction.
    Valtype16 first = elfcpp::Swap<16, big_endian>::readval(view);
    Valtype16 second = elfcpp::Swap<16, big_endian>::readval(view + 2);
    Valtype32 val;

    if (micromips_reloc(r_type)
        || (r_type == elfcpp::R_MIPS16_26 && !jal_shuffle))
      val = first << 16 | second;
    else if (r_type != elfcpp::R_MIPS16_26)
      val = (((first & 0xf800) << 16) | ((second & 0xffe0) << 11)
             | ((first & 0x1f) << 11) | (first & 0x7e0) | (second & 0x1f));
    else
      val = (((first & 0xfc00) << 16) | ((first & 0x3e0) << 11)
             | ((first & 0x1f) << 21) | second);

    elfcpp::Swap<32, big_endian>::writeval(view, val);
  }

  static void
  mips_reloc_shuffle(unsigned char* view, unsigned int r_type, bool jal_shuffle)
  {
    if (!mips16_reloc(r_type)
        && !should_shuffle_micromips_reloc(r_type))
      return;

    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(view);
    Valtype16 first, second;

    if (micromips_reloc(r_type)
        || (r_type == elfcpp::R_MIPS16_26 && !jal_shuffle))
      {
        second = val & 0xffff;
        first = val >> 16;
      }
    else if (r_type != elfcpp::R_MIPS16_26)
      {
        second = ((val >> 11) & 0xffe0) | (val & 0x1f);
        first = ((val >> 16) & 0xf800) | ((val >> 11) & 0x1f) | (val & 0x7e0);
      }
    else
      {
        second = val & 0xffff;
        first = ((val >> 16) & 0xfc00) | ((val >> 11) & 0x3e0)
                 | ((val >> 21) & 0x1f);
      }

    elfcpp::Swap<16, big_endian>::writeval(view + 2, second);
    elfcpp::Swap<16, big_endian>::writeval(view, first);
  }

  // R_MIPS_16: S + sign-extend(A)
  static inline typename This::Status
  rel16(unsigned char* view, const Mips_relobj<size, big_endian>* object,
        const Symbol_value<size>* psymval, Mips_address addend_a,
        bool extract_addend, bool calculate_only, Valtype* calculated_value)
  {
    Valtype16* wv = reinterpret_cast<Valtype16*>(view);
    Valtype16 val = elfcpp::Swap<16, big_endian>::readval(wv);

    Valtype addend = (extract_addend ? Bits<16>::sign_extend32(val)
                                     : addend_a);

    Valtype x = psymval->value(object, addend);
    val = Bits<16>::bit_select32(val, x, 0xffffU);

    if (calculate_only)
      {
        *calculated_value = x;
        return This::STATUS_OKAY;
      }
    else
      elfcpp::Swap<16, big_endian>::writeval(wv, val);

    return check_overflow<16>(x);
  }

  // R_MIPS_32: S + A
  static inline typename This::Status
  rel32(unsigned char* view, const Mips_relobj<size, big_endian>* object,
        const Symbol_value<size>* psymval, Mips_address addend_a,
        bool extract_addend, bool calculate_only, Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype addend = (extract_addend
                        ? elfcpp::Swap<32, big_endian>::readval(wv)
                        : addend_a);
    Valtype x = psymval->value(object, addend);

    if (calculate_only)
      *calculated_value = x;
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, x);

    return This::STATUS_OKAY;
  }

  // R_MIPS_JALR, R_MICROMIPS_JALR
  static inline typename This::Status
  reljalr(unsigned char* view, const Mips_relobj<size, big_endian>* object,
          const Symbol_value<size>* psymval, Mips_address address,
          Mips_address addend_a, bool extract_addend, bool cross_mode_jump,
          unsigned int r_type, bool jalr_to_bal, bool jr_to_b,
          bool calculate_only, Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype addend = extract_addend ? 0 : addend_a;
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);

    // Try converting J(AL)R to B(AL), if the target is in range.
    if (r_type == elfcpp::R_MIPS_JALR
        && !cross_mode_jump
        && ((jalr_to_bal && val == 0x0320f809)    // jalr t9
            || (jr_to_b && val == 0x03200008)))   // jr t9
      {
        int offset = psymval->value(object, addend) - (address + 4);
        if (!Bits<18>::has_overflow32(offset))
          {
            if (val == 0x03200008)   // jr t9
              val = 0x10000000 | (((Valtype32)offset >> 2) & 0xffff);  // b addr
            else
              val = 0x04110000 | (((Valtype32)offset >> 2) & 0xffff); //bal addr
          }
      }

    if (calculate_only)
      *calculated_value = val;
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return This::STATUS_OKAY;
  }

  // R_MIPS_PC32: S + A - P
  static inline typename This::Status
  relpc32(unsigned char* view, const Mips_relobj<size, big_endian>* object,
          const Symbol_value<size>* psymval, Mips_address address,
          Mips_address addend_a, bool extract_addend, bool calculate_only,
          Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype addend = (extract_addend
                        ? elfcpp::Swap<32, big_endian>::readval(wv)
                        : addend_a);
    Valtype x = psymval->value(object, addend) - address;

    if (calculate_only)
       *calculated_value = x;
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, x);

    return This::STATUS_OKAY;
  }

  // R_MIPS_26, R_MIPS16_26, R_MICROMIPS_26_S1
  static inline typename This::Status
  rel26(unsigned char* view, const Mips_relobj<size, big_endian>* object,
        const Symbol_value<size>* psymval, Mips_address address,
        bool local, Mips_address addend_a, bool extract_addend,
        const Symbol* gsym, bool cross_mode_jump, unsigned int r_type,
        bool jal_to_bal, bool calculate_only, Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);

    Valtype addend;
    if (extract_addend)
      {
        if (r_type == elfcpp::R_MICROMIPS_26_S1)
          addend = (val & 0x03ffffff) << 1;
        else
          addend = (val & 0x03ffffff) << 2;
      }
    else
      addend = addend_a;

    // Make sure the target of JALX is word-aligned.  Bit 0 must be
    // the correct ISA mode selector and bit 1 must be 0.
    if (!calculate_only && cross_mode_jump
        && (psymval->value(object, 0) & 3) != (r_type == elfcpp::R_MIPS_26))
      {
        gold_warning(_("JALX to a non-word-aligned address"));
        return This::STATUS_BAD_RELOC;
      }

    // Shift is 2, unusually, for microMIPS JALX.
    unsigned int shift =
        (!cross_mode_jump && r_type == elfcpp::R_MICROMIPS_26_S1) ? 1 : 2;

    Valtype x;
    if (local)
      x = addend | ((address + 4) & (0xfc000000 << shift));
    else
      {
        if (shift == 1)
          x = Bits<27>::sign_extend32(addend);
        else
          x = Bits<28>::sign_extend32(addend);
      }
    x = psymval->value(object, x) >> shift;

    if (!calculate_only && !local && !gsym->is_weak_undefined()
        && ((x >> 26) != ((address + 4) >> (26 + shift))))
      return This::STATUS_OVERFLOW;

    val = Bits<32>::bit_select32(val, x, 0x03ffffff);

    // If required, turn JAL into JALX.
    if (cross_mode_jump)
      {
        bool ok;
        Valtype32 opcode = val >> 26;
        Valtype32 jalx_opcode;

        // Check to see if the opcode is already JAL or JALX.
        if (r_type == elfcpp::R_MIPS16_26)
          {
            ok = (opcode == 0x6) || (opcode == 0x7);
            jalx_opcode = 0x7;
          }
        else if (r_type == elfcpp::R_MICROMIPS_26_S1)
          {
            ok = (opcode == 0x3d) || (opcode == 0x3c);
            jalx_opcode = 0x3c;
          }
        else
          {
            ok = (opcode == 0x3) || (opcode == 0x1d);
            jalx_opcode = 0x1d;
          }

        // If the opcode is not JAL or JALX, there's a problem.  We cannot
        // convert J or JALS to JALX.
        if (!calculate_only && !ok)
          {
            gold_error(_("Unsupported jump between ISA modes; consider "
                         "recompiling with interlinking enabled."));
            return This::STATUS_BAD_RELOC;
          }

        // Make this the JALX opcode.
        val = (val & ~(0x3f << 26)) | (jalx_opcode << 26);
      }

    // Try converting JAL to BAL, if the target is in range.
    if (!parameters->options().relocatable()
        && !cross_mode_jump
        && ((jal_to_bal
            && r_type == elfcpp::R_MIPS_26
            && (val >> 26) == 0x3)))    // jal addr
      {
        Valtype32 dest = (x << 2) | (((address + 4) >> 28) << 28);
        int offset = dest - (address + 4);
        if (!Bits<18>::has_overflow32(offset))
          {
            if (val == 0x03200008)   // jr t9
              val = 0x10000000 | (((Valtype32)offset >> 2) & 0xffff);  // b addr
            else
              val = 0x04110000 | (((Valtype32)offset >> 2) & 0xffff); //bal addr
          }
      }

    if (calculate_only)
      *calculated_value = val;
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return This::STATUS_OKAY;
  }

  // R_MIPS_PC16
  static inline typename This::Status
  relpc16(unsigned char* view, const Mips_relobj<size, big_endian>* object,
          const Symbol_value<size>* psymval, Mips_address address,
          Mips_address addend_a, bool extract_addend, bool calculate_only,
          Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);

    Valtype addend = (extract_addend
                      ? Bits<18>::sign_extend32((val & 0xffff) << 2)
                      : addend_a);

    Valtype x = psymval->value(object, addend) - address;
    val = Bits<16>::bit_select32(val, x >> 2, 0xffff);

    if (calculate_only)
      {
        *calculated_value = x >> 2;
        return This::STATUS_OKAY;
      }
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    if (psymval->value(object, addend) & 3)
      return This::STATUS_PCREL_UNALIGNED;

    return check_overflow<18>(x);
  }

  // R_MIPS_PC21_S2
  static inline typename This::Status
  relpc21(unsigned char* view, const Mips_relobj<size, big_endian>* object,
          const Symbol_value<size>* psymval, Mips_address address,
          Mips_address addend_a, bool extract_addend, bool calculate_only,
          Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);

    Valtype addend = (extract_addend
                      ? Bits<23>::sign_extend32((val & 0x1fffff) << 2)
                      : addend_a);

    Valtype x = psymval->value(object, addend) - address;
    val = Bits<21>::bit_select32(val, x >> 2, 0x1fffff);

    if (calculate_only)
      {
        *calculated_value = x >> 2;
        return This::STATUS_OKAY;
      }
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    if (psymval->value(object, addend) & 3)
      return This::STATUS_PCREL_UNALIGNED;

    return check_overflow<23>(x);
  }

  // R_MIPS_PC26_S2
  static inline typename This::Status
  relpc26(unsigned char* view, const Mips_relobj<size, big_endian>* object,
          const Symbol_value<size>* psymval, Mips_address address,
          Mips_address addend_a, bool extract_addend, bool calculate_only,
          Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);

    Valtype addend = (extract_addend
                      ? Bits<28>::sign_extend32((val & 0x3ffffff) << 2)
                      : addend_a);

    Valtype x = psymval->value(object, addend) - address;
    val = Bits<26>::bit_select32(val, x >> 2, 0x3ffffff);

    if (calculate_only)
      {
        *calculated_value = x >> 2;
        return This::STATUS_OKAY;
      }
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    if (psymval->value(object, addend) & 3)
      return This::STATUS_PCREL_UNALIGNED;

    return check_overflow<28>(x);
  }

  // R_MIPS_PC18_S3
  static inline typename This::Status
  relpc18(unsigned char* view, const Mips_relobj<size, big_endian>* object,
          const Symbol_value<size>* psymval, Mips_address address,
          Mips_address addend_a, bool extract_addend, bool calculate_only,
          Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);

    Valtype addend = (extract_addend
                      ? Bits<21>::sign_extend32((val & 0x3ffff) << 3)
                      : addend_a);

    Valtype x = psymval->value(object, addend) - ((address | 7) ^ 7);
    val = Bits<18>::bit_select32(val, x >> 3, 0x3ffff);

    if (calculate_only)
      {
        *calculated_value = x >> 3;
        return This::STATUS_OKAY;
      }
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    if (psymval->value(object, addend) & 7)
      return This::STATUS_PCREL_UNALIGNED;

    return check_overflow<21>(x);
  }

  // R_MIPS_PC19_S2
  static inline typename This::Status
  relpc19(unsigned char* view, const Mips_relobj<size, big_endian>* object,
          const Symbol_value<size>* psymval, Mips_address address,
          Mips_address addend_a, bool extract_addend, bool calculate_only,
          Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);

    Valtype addend = (extract_addend
                      ? Bits<21>::sign_extend32((val & 0x7ffff) << 2)
                      : addend_a);

    Valtype x = psymval->value(object, addend) - address;
    val = Bits<19>::bit_select32(val, x >> 2, 0x7ffff);

    if (calculate_only)
      {
        *calculated_value = x >> 2;
        return This::STATUS_OKAY;
      }
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    if (psymval->value(object, addend) & 3)
      return This::STATUS_PCREL_UNALIGNED;

    return check_overflow<21>(x);
  }

  // R_MIPS_PCHI16
  static inline typename This::Status
  relpchi16(unsigned char* view, const Mips_relobj<size, big_endian>* object,
            const Symbol_value<size>* psymval, Mips_address addend,
            Mips_address address, unsigned int r_sym, bool extract_addend)
  {
    // Record the relocation.  It will be resolved when we find pclo16 part.
    pchi16_relocs.push_back(reloc_high<size, big_endian>(view, object, psymval,
                            addend, 0, r_sym, extract_addend, address));
    return This::STATUS_OKAY;
  }

  // R_MIPS_PCHI16
  static inline typename This::Status
  do_relpchi16(unsigned char* view, const Mips_relobj<size, big_endian>* object,
             const Symbol_value<size>* psymval, Mips_address addend_hi,
             Mips_address address, bool extract_addend, Valtype32 addend_lo,
             bool calculate_only, Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);

    Valtype addend = (extract_addend ? ((val & 0xffff) << 16) + addend_lo
                                       : addend_hi);

    Valtype value = psymval->value(object, addend) - address;
    Valtype x = ((value + 0x8000) >> 16) & 0xffff;
    val = Bits<32>::bit_select32(val, x, 0xffff);

    if (calculate_only)
      *calculated_value = x;
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return This::STATUS_OKAY;
  }

  // R_MIPS_PCLO16
  static inline typename This::Status
  relpclo16(unsigned char* view, const Mips_relobj<size, big_endian>* object,
            const Symbol_value<size>* psymval, Mips_address addend_a,
            bool extract_addend, Mips_address address, unsigned int r_sym,
            unsigned int rel_type, bool calculate_only,
            Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);

    Valtype addend = (extract_addend ? Bits<16>::sign_extend32(val & 0xffff)
                                     : addend_a);

    if (rel_type == elfcpp::SHT_REL)
      {
        // Resolve pending R_MIPS_PCHI16 relocations.
        typename std::list<reloc_high<size, big_endian> >::iterator it =
            pchi16_relocs.begin();
        while (it != pchi16_relocs.end())
          {
            reloc_high<size, big_endian> pchi16 = *it;
            if (pchi16.r_sym == r_sym)
              {
                do_relpchi16(pchi16.view, pchi16.object, pchi16.psymval,
                             pchi16.addend, pchi16.address,
                             pchi16.extract_addend, addend, calculate_only,
                             calculated_value);
                it = pchi16_relocs.erase(it);
              }
            else
              ++it;
          }
      }

    // Resolve R_MIPS_PCLO16 relocation.
    Valtype x = psymval->value(object, addend) - address;
    val = Bits<32>::bit_select32(val, x, 0xffff);

    if (calculate_only)
      *calculated_value = x;
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return This::STATUS_OKAY;
  }

  // R_MICROMIPS_PC7_S1
  static inline typename This::Status
  relmicromips_pc7_s1(unsigned char* view,
                      const Mips_relobj<size, big_endian>* object,
                      const Symbol_value<size>* psymval, Mips_address address,
                      Mips_address addend_a, bool extract_addend,
                      bool calculate_only, Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);

    Valtype addend = extract_addend ? Bits<8>::sign_extend32((val & 0x7f) << 1)
                                    : addend_a;

    Valtype x = psymval->value(object, addend) - address;
    val = Bits<16>::bit_select32(val, x >> 1, 0x7f);

    if (calculate_only)
      {
        *calculated_value = x >> 1;
        return This::STATUS_OKAY;
      }
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return check_overflow<8>(x);
  }

  // R_MICROMIPS_PC10_S1
  static inline typename This::Status
  relmicromips_pc10_s1(unsigned char* view,
                       const Mips_relobj<size, big_endian>* object,
                       const Symbol_value<size>* psymval, Mips_address address,
                       Mips_address addend_a, bool extract_addend,
                       bool calculate_only, Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);

    Valtype addend = (extract_addend
                      ? Bits<11>::sign_extend32((val & 0x3ff) << 1)
                      : addend_a);

    Valtype x = psymval->value(object, addend) - address;
    val = Bits<16>::bit_select32(val, x >> 1, 0x3ff);

    if (calculate_only)
      {
        *calculated_value = x >> 1;
        return This::STATUS_OKAY;
      }
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return check_overflow<11>(x);
  }

  // R_MICROMIPS_PC16_S1
  static inline typename This::Status
  relmicromips_pc16_s1(unsigned char* view,
                       const Mips_relobj<size, big_endian>* object,
                       const Symbol_value<size>* psymval, Mips_address address,
                       Mips_address addend_a, bool extract_addend,
                       bool calculate_only, Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);

    Valtype addend = (extract_addend
                      ? Bits<17>::sign_extend32((val & 0xffff) << 1)
                      : addend_a);

    Valtype x = psymval->value(object, addend) - address;
    val = Bits<16>::bit_select32(val, x >> 1, 0xffff);

    if (calculate_only)
      {
        *calculated_value = x >> 1;
        return This::STATUS_OKAY;
      }
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return check_overflow<17>(x);
  }

  // R_MIPS_HI16, R_MIPS16_HI16, R_MICROMIPS_HI16,
  static inline typename This::Status
  relhi16(unsigned char* view, const Mips_relobj<size, big_endian>* object,
          const Symbol_value<size>* psymval, Mips_address addend,
          Mips_address address, bool gp_disp, unsigned int r_type,
          unsigned int r_sym, bool extract_addend)
  {
    // Record the relocation.  It will be resolved when we find lo16 part.
    hi16_relocs.push_back(reloc_high<size, big_endian>(view, object, psymval,
                          addend, r_type, r_sym, extract_addend, address,
                          gp_disp));
    return This::STATUS_OKAY;
  }

  // R_MIPS_HI16, R_MIPS16_HI16, R_MICROMIPS_HI16,
  static inline typename This::Status
  do_relhi16(unsigned char* view, const Mips_relobj<size, big_endian>* object,
             const Symbol_value<size>* psymval, Mips_address addend_hi,
             Mips_address address, bool is_gp_disp, unsigned int r_type,
             bool extract_addend, Valtype32 addend_lo,
             Target_mips<size, big_endian>* target, bool calculate_only,
             Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);

    Valtype addend = (extract_addend ? ((val & 0xffff) << 16) + addend_lo
                                       : addend_hi);

    Valtype32 value;
    if (!is_gp_disp)
      value = psymval->value(object, addend);
    else
      {
        // For MIPS16 ABI code we generate this sequence
        //    0: li      $v0,%hi(_gp_disp)
        //    4: addiupc $v1,%lo(_gp_disp)
        //    8: sll     $v0,16
        //   12: addu    $v0,$v1
        //   14: move    $gp,$v0
        // So the offsets of hi and lo relocs are the same, but the
        // base $pc is that used by the ADDIUPC instruction at $t9 + 4.
        // ADDIUPC clears the low two bits of the instruction address,
        // so the base is ($t9 + 4) & ~3.
        Valtype32 gp_disp;
        if (r_type == elfcpp::R_MIPS16_HI16)
          gp_disp = (target->adjusted_gp_value(object)
                     - ((address + 4) & ~0x3));
        // The microMIPS .cpload sequence uses the same assembly
        // instructions as the traditional psABI version, but the
        // incoming $t9 has the low bit set.
        else if (r_type == elfcpp::R_MICROMIPS_HI16)
          gp_disp = target->adjusted_gp_value(object) - address - 1;
        else
          gp_disp = target->adjusted_gp_value(object) - address;
        value = gp_disp + addend;
      }
    Valtype x = ((value + 0x8000) >> 16) & 0xffff;
    val = Bits<32>::bit_select32(val, x, 0xffff);

    if (calculate_only)
      {
        *calculated_value = x;
        return This::STATUS_OKAY;
      }
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return (is_gp_disp ? check_overflow<16>(x)
                       : This::STATUS_OKAY);
  }

  // R_MIPS_GOT16, R_MIPS16_GOT16, R_MICROMIPS_GOT16
  static inline typename This::Status
  relgot16_local(unsigned char* view,
                 const Mips_relobj<size, big_endian>* object,
                 const Symbol_value<size>* psymval, Mips_address addend_a,
                 bool extract_addend, unsigned int r_type, unsigned int r_sym)
  {
    // Record the relocation.  It will be resolved when we find lo16 part.
    got16_relocs.push_back(reloc_high<size, big_endian>(view, object, psymval,
                           addend_a, r_type, r_sym, extract_addend));
    return This::STATUS_OKAY;
  }

  // R_MIPS_GOT16, R_MIPS16_GOT16, R_MICROMIPS_GOT16
  static inline typename This::Status
  do_relgot16_local(unsigned char* view,
                    const Mips_relobj<size, big_endian>* object,
                    const Symbol_value<size>* psymval, Mips_address addend_hi,
                    bool extract_addend, Valtype32 addend_lo,
                    Target_mips<size, big_endian>* target, bool calculate_only,
                    Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);

    Valtype addend = (extract_addend ? ((val & 0xffff) << 16) + addend_lo
                                       : addend_hi);

    // Find GOT page entry.
    Mips_address value = ((psymval->value(object, addend) + 0x8000) >> 16)
                          & 0xffff;
    value <<= 16;
    unsigned int got_offset =
      target->got_section()->get_got_page_offset(value, object);

    // Resolve the relocation.
    Valtype x = target->got_section()->gp_offset(got_offset, object);
    val = Bits<32>::bit_select32(val, x, 0xffff);

    if (calculate_only)
      {
        *calculated_value = x;
        return This::STATUS_OKAY;
      }
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return check_overflow<16>(x);
  }

  // R_MIPS_LO16, R_MIPS16_LO16, R_MICROMIPS_LO16, R_MICROMIPS_HI0_LO16
  static inline typename This::Status
  rello16(Target_mips<size, big_endian>* target, unsigned char* view,
          const Mips_relobj<size, big_endian>* object,
          const Symbol_value<size>* psymval, Mips_address addend_a,
          bool extract_addend, Mips_address address, bool is_gp_disp,
          unsigned int r_type, unsigned int r_sym, unsigned int rel_type,
          bool calculate_only, Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);

    Valtype addend = (extract_addend ? Bits<16>::sign_extend32(val & 0xffff)
                                     : addend_a);

    if (rel_type == elfcpp::SHT_REL)
      {
        typename This::Status reloc_status = This::STATUS_OKAY;
        // Resolve pending R_MIPS_HI16 relocations.
        typename std::list<reloc_high<size, big_endian> >::iterator it =
          hi16_relocs.begin();
        while (it != hi16_relocs.end())
          {
            reloc_high<size, big_endian> hi16 = *it;
            if (hi16.r_sym == r_sym
                && is_matching_lo16_reloc(hi16.r_type, r_type))
              {
                mips_reloc_unshuffle(hi16.view, hi16.r_type, false);
                reloc_status = do_relhi16(hi16.view, hi16.object, hi16.psymval,
                                       hi16.addend, hi16.address, hi16.gp_disp,
                                       hi16.r_type, hi16.extract_addend, addend,
                                       target, calculate_only, calculated_value);
                mips_reloc_shuffle(hi16.view, hi16.r_type, false);
                if (reloc_status == This::STATUS_OVERFLOW)
                  return This::STATUS_OVERFLOW;
                it = hi16_relocs.erase(it);
              }
            else
              ++it;
          }

        // Resolve pending local R_MIPS_GOT16 relocations.
        typename std::list<reloc_high<size, big_endian> >::iterator it2 =
          got16_relocs.begin();
        while (it2 != got16_relocs.end())
          {
            reloc_high<size, big_endian> got16 = *it2;
            if (got16.r_sym == r_sym
                && is_matching_lo16_reloc(got16.r_type, r_type))
              {
                mips_reloc_unshuffle(got16.view, got16.r_type, false);

                reloc_status = do_relgot16_local(got16.view, got16.object,
                                     got16.psymval, got16.addend,
                                     got16.extract_addend, addend, target,
                                     calculate_only, calculated_value);

                mips_reloc_shuffle(got16.view, got16.r_type, false);
                if (reloc_status == This::STATUS_OVERFLOW)
                  return This::STATUS_OVERFLOW;
                it2 = got16_relocs.erase(it2);
              }
            else
              ++it2;
          }
      }

    // Resolve R_MIPS_LO16 relocation.
    Valtype x;
    if (!is_gp_disp)
      x = psymval->value(object, addend);
    else
      {
        // See the comment for R_MIPS16_HI16 above for the reason
        // for this conditional.
        Valtype32 gp_disp;
        if (r_type == elfcpp::R_MIPS16_LO16)
          gp_disp = target->adjusted_gp_value(object) - (address & ~0x3);
        else if (r_type == elfcpp::R_MICROMIPS_LO16
                 || r_type == elfcpp::R_MICROMIPS_HI0_LO16)
          gp_disp = target->adjusted_gp_value(object) - address + 3;
        else
          gp_disp = target->adjusted_gp_value(object) - address + 4;
        // The MIPS ABI requires checking the R_MIPS_LO16 relocation
        // for overflow.  Relocations against _gp_disp are normally
        // generated from the .cpload pseudo-op.  It generates code
        // that normally looks like this:

        //   lui    $gp,%hi(_gp_disp)
        //   addiu  $gp,$gp,%lo(_gp_disp)
        //   addu   $gp,$gp,$t9

        // Here $t9 holds the address of the function being called,
        // as required by the MIPS ELF ABI.  The R_MIPS_LO16
        // relocation can easily overflow in this situation, but the
        // R_MIPS_HI16 relocation will handle the overflow.
        // Therefore, we consider this a bug in the MIPS ABI, and do
        // not check for overflow here.
        x = gp_disp + addend;
      }
    val = Bits<32>::bit_select32(val, x, 0xffff);

    if (calculate_only)
      *calculated_value = x;
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return This::STATUS_OKAY;
  }

  // R_MIPS_CALL16, R_MIPS16_CALL16, R_MICROMIPS_CALL16
  // R_MIPS_GOT16, R_MIPS16_GOT16, R_MICROMIPS_GOT16
  // R_MIPS_TLS_GD, R_MIPS16_TLS_GD, R_MICROMIPS_TLS_GD
  // R_MIPS_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL, R_MICROMIPS_TLS_GOTTPREL
  // R_MIPS_TLS_LDM, R_MIPS16_TLS_LDM, R_MICROMIPS_TLS_LDM
  // R_MIPS_GOT_DISP, R_MICROMIPS_GOT_DISP
  static inline typename This::Status
  relgot(unsigned char* view, int gp_offset, bool calculate_only,
         Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
    Valtype x = gp_offset;
    val = Bits<32>::bit_select32(val, x, 0xffff);

    if (calculate_only)
      {
        *calculated_value = x;
        return This::STATUS_OKAY;
      }
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return check_overflow<16>(x);
  }

  // R_MIPS_EH
  static inline typename This::Status
  releh(unsigned char* view, int gp_offset, bool calculate_only,
        Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype x = gp_offset;

    if (calculate_only)
      {
        *calculated_value = x;
        return This::STATUS_OKAY;
      }
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, x);

    return check_overflow<32>(x);
  }

  // R_MIPS_GOT_PAGE, R_MICROMIPS_GOT_PAGE
  static inline typename This::Status
  relgotpage(Target_mips<size, big_endian>* target, unsigned char* view,
             const Mips_relobj<size, big_endian>* object,
             const Symbol_value<size>* psymval, Mips_address addend_a,
             bool extract_addend, bool calculate_only,
             Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(view);
    Valtype addend = extract_addend ? val & 0xffff : addend_a;

    // Find a GOT page entry that points to within 32KB of symbol + addend.
    Mips_address value = (psymval->value(object, addend) + 0x8000) & ~0xffff;
    unsigned int  got_offset =
      target->got_section()->get_got_page_offset(value, object);

    Valtype x = target->got_section()->gp_offset(got_offset, object);
    val = Bits<32>::bit_select32(val, x, 0xffff);

    if (calculate_only)
      {
        *calculated_value = x;
        return This::STATUS_OKAY;
      }
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return check_overflow<16>(x);
  }

  // R_MIPS_GOT_OFST, R_MICROMIPS_GOT_OFST
  static inline typename This::Status
  relgotofst(Target_mips<size, big_endian>* target, unsigned char* view,
             const Mips_relobj<size, big_endian>* object,
             const Symbol_value<size>* psymval, Mips_address addend_a,
             bool extract_addend, bool local, bool calculate_only,
             Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(view);
    Valtype addend = extract_addend ? val & 0xffff : addend_a;

    // For a local symbol, find a GOT page entry that points to within 32KB of
    // symbol + addend.  Relocation value is the offset of the GOT page entry's
    // value from symbol + addend.
    // For a global symbol, relocation value is addend.
    Valtype x;
    if (local)
      {
        // Find GOT page entry.
        Mips_address value = ((psymval->value(object, addend) + 0x8000)
                              & ~0xffff);
        target->got_section()->get_got_page_offset(value, object);

        x = psymval->value(object, addend) - value;
      }
    else
      x = addend;
    val = Bits<32>::bit_select32(val, x, 0xffff);

    if (calculate_only)
      {
        *calculated_value = x;
        return This::STATUS_OKAY;
      }
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return check_overflow<16>(x);
  }

  // R_MIPS_GOT_HI16, R_MIPS_CALL_HI16,
  // R_MICROMIPS_GOT_HI16, R_MICROMIPS_CALL_HI16
  static inline typename This::Status
  relgot_hi16(unsigned char* view, int gp_offset, bool calculate_only,
              Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
    Valtype x = gp_offset;
    x = ((x + 0x8000) >> 16) & 0xffff;
    val = Bits<32>::bit_select32(val, x, 0xffff);

    if (calculate_only)
      *calculated_value = x;
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return This::STATUS_OKAY;
  }

  // R_MIPS_GOT_LO16, R_MIPS_CALL_LO16,
  // R_MICROMIPS_GOT_LO16, R_MICROMIPS_CALL_LO16
  static inline typename This::Status
  relgot_lo16(unsigned char* view, int gp_offset, bool calculate_only,
              Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
    Valtype x = gp_offset;
    val = Bits<32>::bit_select32(val, x, 0xffff);

    if (calculate_only)
      *calculated_value = x;
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return This::STATUS_OKAY;
  }

  // R_MIPS_GPREL16, R_MIPS16_GPREL, R_MIPS_LITERAL, R_MICROMIPS_LITERAL
  // R_MICROMIPS_GPREL7_S2, R_MICROMIPS_GPREL16
  static inline typename This::Status
  relgprel(unsigned char* view, const Mips_relobj<size, big_endian>* object,
           const Symbol_value<size>* psymval, Mips_address gp,
           Mips_address addend_a, bool extract_addend, bool local,
           unsigned int r_type, bool calculate_only,
           Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);

    Valtype addend;
    if (extract_addend)
      {
        if (r_type == elfcpp::R_MICROMIPS_GPREL7_S2)
          addend = (val & 0x7f) << 2;
        else
          addend = val & 0xffff;
        // Only sign-extend the addend if it was extracted from the
        // instruction.  If the addend was separate, leave it alone,
        // otherwise we may lose significant bits.
        addend = Bits<16>::sign_extend32(addend);
      }
    else
      addend = addend_a;

    Valtype x = psymval->value(object, addend) - gp;

    // If the symbol was local, any earlier relocatable links will
    // have adjusted its addend with the gp offset, so compensate
    // for that now.  Don't do it for symbols forced local in this
    // link, though, since they won't have had the gp offset applied
    // to them before.
    if (local)
      x += object->gp_value();

    if (r_type == elfcpp::R_MICROMIPS_GPREL7_S2)
      val = Bits<32>::bit_select32(val, x, 0x7f);
    else
      val = Bits<32>::bit_select32(val, x, 0xffff);

    if (calculate_only)
      {
        *calculated_value = x;
        return This::STATUS_OKAY;
      }
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    if (check_overflow<16>(x) == This::STATUS_OVERFLOW)
      {
        gold_error(_("small-data section exceeds 64KB; lower small-data size "
                     "limit (see option -G)"));
        return This::STATUS_OVERFLOW;
      }
    return This::STATUS_OKAY;
  }

  // R_MIPS_GPREL32
  static inline typename This::Status
  relgprel32(unsigned char* view, const Mips_relobj<size, big_endian>* object,
             const Symbol_value<size>* psymval, Mips_address gp,
             Mips_address addend_a, bool extract_addend, bool calculate_only,
             Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
    Valtype addend = extract_addend ? val : addend_a;

    // R_MIPS_GPREL32 relocations are defined for local symbols only.
    Valtype x = psymval->value(object, addend) + object->gp_value() - gp;

    if (calculate_only)
      *calculated_value = x;
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, x);

    return This::STATUS_OKAY;
 }

  // R_MIPS_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16, R_MICROMIPS_TLS_TPREL_HI16
  // R_MIPS_TLS_DTPREL_HI16, R_MIPS16_TLS_DTPREL_HI16,
  // R_MICROMIPS_TLS_DTPREL_HI16
  static inline typename This::Status
  tlsrelhi16(unsigned char* view, const Mips_relobj<size, big_endian>* object,
             const Symbol_value<size>* psymval, Valtype32 tp_offset,
             Mips_address addend_a, bool extract_addend, bool calculate_only,
             Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
    Valtype addend = extract_addend ? val & 0xffff : addend_a;

    // tls symbol values are relative to tls_segment()->vaddr()
    Valtype x = ((psymval->value(object, addend) - tp_offset) + 0x8000) >> 16;
    val = Bits<32>::bit_select32(val, x, 0xffff);

    if (calculate_only)
      *calculated_value = x;
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return This::STATUS_OKAY;
  }

  // R_MIPS_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16, R_MICROMIPS_TLS_TPREL_LO16,
  // R_MIPS_TLS_DTPREL_LO16, R_MIPS16_TLS_DTPREL_LO16,
  // R_MICROMIPS_TLS_DTPREL_LO16,
  static inline typename This::Status
  tlsrello16(unsigned char* view, const Mips_relobj<size, big_endian>* object,
             const Symbol_value<size>* psymval, Valtype32 tp_offset,
             Mips_address addend_a, bool extract_addend, bool calculate_only,
             Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
    Valtype addend = extract_addend ? val & 0xffff : addend_a;

    // tls symbol values are relative to tls_segment()->vaddr()
    Valtype x = psymval->value(object, addend) - tp_offset;
    val = Bits<32>::bit_select32(val, x, 0xffff);

    if (calculate_only)
      *calculated_value = x;
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return This::STATUS_OKAY;
  }

  // R_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL64,
  // R_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL64
  static inline typename This::Status
  tlsrel32(unsigned char* view, const Mips_relobj<size, big_endian>* object,
           const Symbol_value<size>* psymval, Valtype32 tp_offset,
           Mips_address addend_a, bool extract_addend, bool calculate_only,
           Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
    Valtype addend = extract_addend ? val : addend_a;

    // tls symbol values are relative to tls_segment()->vaddr()
    Valtype x = psymval->value(object, addend) - tp_offset;

    if (calculate_only)
      *calculated_value = x;
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, x);

    return This::STATUS_OKAY;
  }

  // R_MIPS_SUB, R_MICROMIPS_SUB
  static inline typename This::Status
  relsub(unsigned char* view, const Mips_relobj<size, big_endian>* object,
         const Symbol_value<size>* psymval, Mips_address addend_a,
         bool extract_addend, bool calculate_only, Valtype* calculated_value)
  {
    Valtype64* wv = reinterpret_cast<Valtype64*>(view);
    Valtype64 addend = (extract_addend
                        ? elfcpp::Swap<64, big_endian>::readval(wv)
                        : addend_a);

    Valtype64 x = psymval->value(object, -addend);
    if (calculate_only)
      *calculated_value = x;
    else
      elfcpp::Swap<64, big_endian>::writeval(wv, x);

    return This::STATUS_OKAY;
  }

  // R_MIPS_64: S + A
  static inline typename This::Status
  rel64(unsigned char* view, const Mips_relobj<size, big_endian>* object,
        const Symbol_value<size>* psymval, Mips_address addend_a,
        bool extract_addend, bool calculate_only, Valtype* calculated_value,
        bool apply_addend_only)
  {
    Valtype64* wv = reinterpret_cast<Valtype64*>(view);
    Valtype64 addend = (extract_addend
                        ? elfcpp::Swap<64, big_endian>::readval(wv)
                        : addend_a);

    Valtype64 x = psymval->value(object, addend);
    if (calculate_only)
      *calculated_value = x;
    else
      {
        if (apply_addend_only)
          x = addend;
        elfcpp::Swap<64, big_endian>::writeval(wv, x);
      }

    return This::STATUS_OKAY;
  }

  // R_MIPS_HIGHER, R_MICROMIPS_HIGHER
  static inline typename This::Status
  relhigher(unsigned char* view, const Mips_relobj<size, big_endian>* object,
            const Symbol_value<size>* psymval, Mips_address addend_a,
            bool extract_addend, bool calculate_only, Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
    Valtype addend = (extract_addend ? Bits<16>::sign_extend32(val & 0xffff)
                                     : addend_a);

    Valtype x = psymval->value(object, addend);
    x = ((x + (uint64_t) 0x80008000) >> 32) & 0xffff;
    val = Bits<32>::bit_select32(val, x, 0xffff);

    if (calculate_only)
      *calculated_value = x;
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return This::STATUS_OKAY;
  }

  // R_MIPS_HIGHEST, R_MICROMIPS_HIGHEST
  static inline typename This::Status
  relhighest(unsigned char* view, const Mips_relobj<size, big_endian>* object,
             const Symbol_value<size>* psymval, Mips_address addend_a,
             bool extract_addend, bool calculate_only,
             Valtype* calculated_value)
  {
    Valtype32* wv = reinterpret_cast<Valtype32*>(view);
    Valtype32 val = elfcpp::Swap<32, big_endian>::readval(wv);
    Valtype addend = (extract_addend ? Bits<16>::sign_extend32(val & 0xffff)
                                     : addend_a);

    Valtype x = psymval->value(object, addend);
    x = ((x + (uint64_t) 0x800080008000llu) >> 48) & 0xffff;
    val = Bits<32>::bit_select32(val, x, 0xffff);

    if (calculate_only)
      *calculated_value = x;
    else
      elfcpp::Swap<32, big_endian>::writeval(wv, val);

    return This::STATUS_OKAY;
  }
};

template<int size, bool big_endian>
typename std::list<reloc_high<size, big_endian> >
    Mips_relocate_functions<size, big_endian>::hi16_relocs;

template<int size, bool big_endian>
typename std::list<reloc_high<size, big_endian> >
    Mips_relocate_functions<size, big_endian>::got16_relocs;

template<int size, bool big_endian>
typename std::list<reloc_high<size, big_endian> >
    Mips_relocate_functions<size, big_endian>::pchi16_relocs;

// Mips_got_info methods.

// Reserve GOT entry for a GOT relocation of type R_TYPE against symbol
// SYMNDX + ADDEND, where SYMNDX is a local symbol in section SHNDX in OBJECT.

template<int size, bool big_endian>
void
Mips_got_info<size, big_endian>::record_local_got_symbol(
    Mips_relobj<size, big_endian>* object, unsigned int symndx,
    Mips_address addend, unsigned int r_type, unsigned int shndx,
    bool is_section_symbol)
{
  Mips_got_entry<size, big_endian>* entry =
    new Mips_got_entry<size, big_endian>(object, symndx, addend,
                                         mips_elf_reloc_tls_type(r_type),
                                         shndx, is_section_symbol);
  this->record_got_entry(entry, object);
}

// Reserve GOT entry for a GOT relocation of type R_TYPE against MIPS_SYM,
// in OBJECT.  FOR_CALL is true if the caller is only interested in
// using the GOT entry for calls.  DYN_RELOC is true if R_TYPE is a dynamic
// relocation.

template<int size, bool big_endian>
void
Mips_got_info<size, big_endian>::record_global_got_symbol(
    Mips_symbol<size>* mips_sym, Mips_relobj<size, big_endian>* object,
    unsigned int r_type, bool dyn_reloc, bool for_call)
{
  if (!for_call)
    mips_sym->set_got_not_only_for_calls();

  // A global symbol in the GOT must also be in the dynamic symbol table.
  if (!mips_sym->needs_dynsym_entry() && !mips_sym->is_forced_local())
    {
      switch (mips_sym->visibility())
        {
        case elfcpp::STV_INTERNAL:
        case elfcpp::STV_HIDDEN:
          mips_sym->set_is_forced_local();
          break;
        default:
          mips_sym->set_needs_dynsym_entry();
          break;
        }
    }

  unsigned char tls_type = mips_elf_reloc_tls_type(r_type);
  if (tls_type == GOT_TLS_NONE)
    this->global_got_symbols_.insert(mips_sym);

  if (dyn_reloc)
    {
      if (mips_sym->global_got_area() == GGA_NONE)
        mips_sym->set_global_got_area(GGA_RELOC_ONLY);
      return;
    }

  Mips_got_entry<size, big_endian>* entry =
    new Mips_got_entry<size, big_endian>(mips_sym, tls_type);

  this->record_got_entry(entry, object);
}

// Add ENTRY to master GOT and to OBJECT's GOT.

template<int size, bool big_endian>
void
Mips_got_info<size, big_endian>::record_got_entry(
    Mips_got_entry<size, big_endian>* entry,
    Mips_relobj<size, big_endian>* object)
{
  this->got_entries_.insert(entry);

  // Create the GOT entry for the OBJECT's GOT.
  Mips_got_info<size, big_endian>* g = object->get_or_create_got_info();
  Mips_got_entry<size, big_endian>* entry2 =
    new Mips_got_entry<size, big_endian>(*entry);

  g->got_entries_.insert(entry2);
}

// Record that OBJECT has a page relocation against symbol SYMNDX and
// that ADDEND is the addend for that relocation.
// This function creates an upper bound on the number of GOT slots
// required; no attempt is made to combine references to non-overridable
// global symbols across multiple input files.

template<int size, bool big_endian>
void
Mips_got_info<size, big_endian>::record_got_page_entry(
    Mips_relobj<size, big_endian>* object, unsigned int symndx, int addend)
{
  struct Got_page_range **range_ptr, *range;
  int old_pages, new_pages;

  // Find the Got_page_entry for this symbol.
  Got_page_entry* entry = new Got_page_entry(object, symndx);
  typename Got_page_entry_set::iterator it =
    this->got_page_entries_.find(entry);
  if (it != this->got_page_entries_.end())
    entry = *it;
  else
    this->got_page_entries_.insert(entry);

  // Add the same entry to the OBJECT's GOT.
  Got_page_entry* entry2 = NULL;
  Mips_got_info<size, big_endian>* g2 = object->get_or_create_got_info();
  if (g2->got_page_entries_.find(entry) == g2->got_page_entries_.end())
    {
      entry2 = new Got_page_entry(*entry);
      g2->got_page_entries_.insert(entry2);
    }

  // Skip over ranges whose maximum extent cannot share a page entry
  // with ADDEND.
  range_ptr = &entry->ranges;
  while (*range_ptr && addend > (*range_ptr)->max_addend + 0xffff)
    range_ptr = &(*range_ptr)->next;

  // If we scanned to the end of the list, or found a range whose
  // minimum extent cannot share a page entry with ADDEND, create
  // a new singleton range.
  range = *range_ptr;
  if (!range || addend < range->min_addend - 0xffff)
    {
      range = new Got_page_range();
      range->next = *range_ptr;
      range->min_addend = addend;
      range->max_addend = addend;

      *range_ptr = range;
      ++entry->num_pages;
      if (entry2 != NULL)
        ++entry2->num_pages;
      ++this->page_gotno_;
      ++g2->page_gotno_;
      return;
    }

  // Remember how many pages the old range contributed.
  old_pages = range->get_max_pages();

  // Update the ranges.
  if (addend < range->min_addend)
    range->min_addend = addend;
  else if (addend > range->max_addend)
    {
      if (range->next && addend >= range->next->min_addend - 0xffff)
        {
          old_pages += range->next->get_max_pages();
          range->max_addend = range->next->max_addend;
          range->next = range->next->next;
        }
      else
        range->max_addend = addend;
    }

  // Record any change in the total estimate.
  new_pages = range->get_max_pages();
  if (old_pages != new_pages)
    {
      entry->num_pages += new_pages - old_pages;
      if (entry2 != NULL)
        entry2->num_pages += new_pages - old_pages;
      this->page_gotno_ += new_pages - old_pages;
      g2->page_gotno_ += new_pages - old_pages;
    }
}

// Create all entries that should be in the local part of the GOT.

template<int size, bool big_endian>
void
Mips_got_info<size, big_endian>::add_local_entries(
    Target_mips<size, big_endian>* target, Layout* layout)
{
  Mips_output_data_got<size, big_endian>* got = target->got_section();
  // First two GOT entries are reserved.  The first entry will be filled at
  // runtime.  The second entry will be used by some runtime loaders.
  got->add_constant(0);
  got->add_constant(target->mips_elf_gnu_got1_mask());

  for (typename Got_entry_set::iterator
       p = this->got_entries_.begin();
       p != this->got_entries_.end();
       ++p)
    {
      Mips_got_entry<size, big_endian>* entry = *p;
      if (entry->is_for_local_symbol() && !entry->is_tls_entry())
        {
          got->add_local(entry->object(), entry->symndx(),
                         GOT_TYPE_STANDARD, entry->addend());
          unsigned int got_offset = entry->object()->local_got_offset(
              entry->symndx(), GOT_TYPE_STANDARD, entry->addend());
          if (got->multi_got() && this->index_ > 0
              && parameters->options().output_is_position_independent())
          {
            if (!entry->is_section_symbol())
              target->rel_dyn_section(layout)->add_local(entry->object(),
                  entry->symndx(), elfcpp::R_MIPS_REL32, got, got_offset);
            else
              target->rel_dyn_section(layout)->add_symbolless_local_addend(
                  entry->object(), entry->symndx(), elfcpp::R_MIPS_REL32,
                  got, got_offset);
          }
        }
    }

  this->add_page_entries(target, layout);

  // Add global entries that should be in the local area.
  for (typename Got_entry_set::iterator
       p = this->got_entries_.begin();
       p != this->got_entries_.end();
       ++p)
    {
      Mips_got_entry<size, big_endian>* entry = *p;
      if (!entry->is_for_global_symbol())
        continue;

      Mips_symbol<size>* mips_sym = entry->sym();
      if (mips_sym->global_got_area() == GGA_NONE && !entry->is_tls_entry())
        {
          unsigned int got_type;
          if (!got->multi_got())
            got_type = GOT_TYPE_STANDARD;
          else
            got_type = GOT_TYPE_STANDARD_MULTIGOT + this->index_;
          if (got->add_global(mips_sym, got_type))
            {
              mips_sym->set_global_gotoffset(mips_sym->got_offset(got_type));
              if (got->multi_got() && this->index_ > 0
                  && parameters->options().output_is_position_independent())
                target->rel_dyn_section(layout)->add_symbolless_global_addend(
                    mips_sym, elfcpp::R_MIPS_REL32, got,
                    mips_sym->got_offset(got_type));
            }
        }
    }
}

// Create GOT page entries.

template<int size, bool big_endian>
void
Mips_got_info<size, big_endian>::add_page_entries(
    Target_mips<size, big_endian>* target, Layout* layout)
{
  if (this->page_gotno_ == 0)
    return;

  Mips_output_data_got<size, big_endian>* got = target->got_section();
  this->got_page_offset_start_ = got->add_constant(0);
  if (got->multi_got() && this->index_ > 0
      && parameters->options().output_is_position_independent())
    target->rel_dyn_section(layout)->add_absolute(elfcpp::R_MIPS_REL32, got,
                                                  this->got_page_offset_start_);
  int num_entries = this->page_gotno_;
  unsigned int prev_offset = this->got_page_offset_start_;
  while (--num_entries > 0)
    {
      unsigned int next_offset = got->add_constant(0);
      if (got->multi_got() && this->index_ > 0
          && parameters->options().output_is_position_independent())
        target->rel_dyn_section(layout)->add_absolute(elfcpp::R_MIPS_REL32, got,
                                                      next_offset);
      gold_assert(next_offset == prev_offset + size/8);
      prev_offset = next_offset;
    }
  this->got_page_offset_next_ = this->got_page_offset_start_;
}

// Create global GOT entries, both GGA_NORMAL and GGA_RELOC_ONLY.

template<int size, bool big_endian>
void
Mips_got_info<size, big_endian>::add_global_entries(
    Target_mips<size, big_endian>* target, Layout* layout,
    unsigned int non_reloc_only_global_gotno)
{
  Mips_output_data_got<size, big_endian>* got = target->got_section();
  // Add GGA_NORMAL entries.
  unsigned int count = 0;
  for (typename Got_entry_set::iterator
       p = this->got_entries_.begin();
       p != this->got_entries_.end();
       ++p)
    {
      Mips_got_entry<size, big_endian>* entry = *p;
      if (!entry->is_for_global_symbol())
        continue;

      Mips_symbol<size>* mips_sym = entry->sym();
      if (mips_sym->global_got_area() != GGA_NORMAL)
        continue;

      unsigned int got_type;
      if (!got->multi_got())
        got_type = GOT_TYPE_STANDARD;
      else
        // In multi-GOT links, global symbol can be in both primary and
        // secondary GOT(s).  By creating custom GOT type
        // (GOT_TYPE_STANDARD_MULTIGOT + got_index) we ensure that symbol
        // is added to secondary GOT(s).
        got_type = GOT_TYPE_STANDARD_MULTIGOT + this->index_;
      if (!got->add_global(mips_sym, got_type))
        continue;

      mips_sym->set_global_gotoffset(mips_sym->got_offset(got_type));
      if (got->multi_got() && this->index_ == 0)
        count++;
      if (got->multi_got() && this->index_ > 0)
        {
          if (parameters->options().output_is_position_independent()
              || (!parameters->doing_static_link()
                  && mips_sym->is_from_dynobj() && !mips_sym->is_undefined()))
            {
              target->rel_dyn_section(layout)->add_global(
                  mips_sym, elfcpp::R_MIPS_REL32, got,
                  mips_sym->got_offset(got_type));
              got->add_secondary_got_reloc(mips_sym->got_offset(got_type),
                                           elfcpp::R_MIPS_REL32, mips_sym);
            }
        }
    }

  if (!got->multi_got() || this->index_ == 0)
    {
      if (got->multi_got())
        {
          // We need to allocate space in the primary GOT for GGA_NORMAL entries
          // of secondary GOTs, to ensure that GOT offsets of GGA_RELOC_ONLY
          // entries correspond to dynamic symbol indexes.
          while (count < non_reloc_only_global_gotno)
            {
              got->add_constant(0);
              ++count;
            }
        }

      // Add GGA_RELOC_ONLY entries.
      got->add_reloc_only_entries();
    }
}

// Create global GOT entries that should be in the GGA_RELOC_ONLY area.

template<int size, bool big_endian>
void
Mips_got_info<size, big_endian>::add_reloc_only_entries(
    Mips_output_data_got<size, big_endian>* got)
{
  for (typename Global_got_entry_set::iterator
       p = this->global_got_symbols_.begin();
       p != this->global_got_symbols_.end();
       ++p)
    {
      Mips_symbol<size>* mips_sym = *p;
      if (mips_sym->global_got_area() == GGA_RELOC_ONLY)
        {
          unsigned int got_type;
          if (!got->multi_got())
            got_type = GOT_TYPE_STANDARD;
          else
            got_type = GOT_TYPE_STANDARD_MULTIGOT;
          if (got->add_global(mips_sym, got_type))
            mips_sym->set_global_gotoffset(mips_sym->got_offset(got_type));
        }
    }
}

// Create TLS GOT entries.

template<int size, bool big_endian>
void
Mips_got_info<size, big_endian>::add_tls_entries(
    Target_mips<size, big_endian>* target, Layout* layout)
{
  Mips_output_data_got<size, big_endian>* got = target->got_section();
  // Add local tls entries.
  for (typename Got_entry_set::iterator
       p = this->got_entries_.begin();
       p != this->got_entries_.end();
       ++p)
    {
      Mips_got_entry<size, big_endian>* entry = *p;
      if (!entry->is_tls_entry() || !entry->is_for_local_symbol())
        continue;

      if (entry->tls_type() == GOT_TLS_GD)
        {
          unsigned int got_type = GOT_TYPE_TLS_PAIR;
          unsigned int r_type1 = (size == 32 ? elfcpp::R_MIPS_TLS_DTPMOD32
                                             : elfcpp::R_MIPS_TLS_DTPMOD64);
          unsigned int r_type2 = (size == 32 ? elfcpp::R_MIPS_TLS_DTPREL32
                                             : elfcpp::R_MIPS_TLS_DTPREL64);

          if (!parameters->doing_static_link())
            {
              got->add_local_pair_with_rel(entry->object(), entry->symndx(),
                                           entry->shndx(), got_type,
                                           target->rel_dyn_section(layout),
                                           r_type1, entry->addend());
              unsigned int got_offset =
                entry->object()->local_got_offset(entry->symndx(), got_type,
                                                  entry->addend());
              got->add_static_reloc(got_offset + size/8, r_type2,
                                    entry->object(), entry->symndx());
            }
          else
            {
              // We are doing a static link.  Mark it as belong to module 1,
              // the executable.
              unsigned int got_offset = got->add_constant(1);
              entry->object()->set_local_got_offset(entry->symndx(), got_type,
                                                    got_offset,
                                                    entry->addend());
              got->add_constant(0);
              got->add_static_reloc(got_offset + size/8, r_type2,
                                    entry->object(), entry->symndx());
            }
        }
      else if (entry->tls_type() == GOT_TLS_IE)
        {
          unsigned int got_type = GOT_TYPE_TLS_OFFSET;
          unsigned int r_type = (size == 32 ? elfcpp::R_MIPS_TLS_TPREL32
                                            : elfcpp::R_MIPS_TLS_TPREL64);
          if (!parameters->doing_static_link())
            got->add_local_with_rel(entry->object(), entry->symndx(), got_type,
                                    target->rel_dyn_section(layout), r_type,
                                    entry->addend());
          else
            {
              got->add_local(entry->object(), entry->symndx(), got_type,
                             entry->addend());
              unsigned int got_offset =
                  entry->object()->local_got_offset(entry->symndx(), got_type,
                                                    entry->addend());
              got->add_static_reloc(got_offset, r_type, entry->object(),
                                    entry->symndx());
            }
        }
      else if (entry->tls_type() == GOT_TLS_LDM)
        {
          unsigned int r_type = (size == 32 ? elfcpp::R_MIPS_TLS_DTPMOD32
                                            : elfcpp::R_MIPS_TLS_DTPMOD64);
          unsigned int got_offset;
          if (!parameters->doing_static_link())
            {
              got_offset = got->add_constant(0);
              target->rel_dyn_section(layout)->add_local(
                  entry->object(), 0, r_type, 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);
          got->set_tls_ldm_offset(got_offset, entry->object());
        }
      else
        gold_unreachable();
    }

  // Add global tls entries.
  for (typename Got_entry_set::iterator
       p = this->got_entries_.begin();
       p != this->got_entries_.end();
       ++p)
    {
      Mips_got_entry<size, big_endian>* entry = *p;
      if (!entry->is_tls_entry() || !entry->is_for_global_symbol())
        continue;

      Mips_symbol<size>* mips_sym = entry->sym();
      if (entry->tls_type() == GOT_TLS_GD)
        {
          unsigned int got_type;
          if (!got->multi_got())
            got_type = GOT_TYPE_TLS_PAIR;
          else
            got_type = GOT_TYPE_TLS_PAIR_MULTIGOT + this->index_;
          unsigned int r_type1 = (size == 32 ? elfcpp::R_MIPS_TLS_DTPMOD32
                                             : elfcpp::R_MIPS_TLS_DTPMOD64);
          unsigned int r_type2 = (size == 32 ? elfcpp::R_MIPS_TLS_DTPREL32
                                             : elfcpp::R_MIPS_TLS_DTPREL64);
          if (!parameters->doing_static_link())
            got->add_global_pair_with_rel(mips_sym, got_type,
                             target->rel_dyn_section(layout), r_type1, r_type2);
          else
            {
              // Add a GOT pair for for R_MIPS_TLS_GD.  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_MIPS_TLS_DTPREL32/64 will be created for
              // the second GOT entry and will be applied by gold.
              unsigned int got_offset = got->add_constant(1);
              mips_sym->set_got_offset(got_type, got_offset);
              got->add_constant(0);
              got->add_static_reloc(got_offset + size/8, r_type2, mips_sym);
            }
        }
      else if (entry->tls_type() == GOT_TLS_IE)
        {
          unsigned int got_type;
          if (!got->multi_got())
            got_type = GOT_TYPE_TLS_OFFSET;
          else
            got_type = GOT_TYPE_TLS_OFFSET_MULTIGOT + this->index_;
          unsigned int r_type = (size == 32 ? elfcpp::R_MIPS_TLS_TPREL32
                                            : elfcpp::R_MIPS_TLS_TPREL64);
          if (!parameters->doing_static_link())
            got->add_global_with_rel(mips_sym, got_type,
                                     target->rel_dyn_section(layout), r_type);
          else
            {
              got->add_global(mips_sym, got_type);
              unsigned int got_offset = mips_sym->got_offset(got_type);
              got->add_static_reloc(got_offset, r_type, mips_sym);
            }
        }
      else
        gold_unreachable();
    }
}

// Decide whether the symbol needs an entry in the global part of the primary
// GOT, setting global_got_area accordingly.  Count the number of global
// symbols that are in the primary GOT only because they have dynamic
// relocations R_MIPS_REL32 against them (reloc_only_gotno).

template<int size, bool big_endian>
void
Mips_got_info<size, big_endian>::count_got_symbols(Symbol_table* symtab)
{
  for (typename Global_got_entry_set::iterator
       p = this->global_got_symbols_.begin();
       p != this->global_got_symbols_.end();
       ++p)
    {
      Mips_symbol<size>* sym = *p;
      // Make a final decision about whether the symbol belongs in the
      // local or global GOT.  Symbols that bind locally can (and in the
      // case of forced-local symbols, must) live in the local GOT.
      // Those that are aren't in the dynamic symbol table must also
      // live in the local GOT.

      if (!sym->should_add_dynsym_entry(symtab)
          || (sym->got_only_for_calls()
              ? symbol_calls_local(sym, sym->should_add_dynsym_entry(symtab))
              : symbol_references_local(sym,
                                        sym->should_add_dynsym_entry(symtab))))
        // The symbol belongs in the local GOT.  We no longer need this
        // entry if it was only used for relocations; those relocations
        // will be against the null or section symbol instead.
        sym->set_global_got_area(GGA_NONE);
      else if (sym->global_got_area() == GGA_RELOC_ONLY)
        {
          ++this->reloc_only_gotno_;
          ++this->global_gotno_ ;
        }
    }
}

// Return the offset of GOT page entry for VALUE.  Initialize the entry with
// VALUE if it is not initialized.

template<int size, bool big_endian>
unsigned int
Mips_got_info<size, big_endian>::get_got_page_offset(Mips_address value,
    Mips_output_data_got<size, big_endian>* got)
{
  typename Got_page_offsets::iterator it = this->got_page_offsets_.find(value);
  if (it != this->got_page_offsets_.end())
    return it->second;

  gold_assert(this->got_page_offset_next_ < this->got_page_offset_start_
              + (size/8) * this->page_gotno_);

  unsigned int got_offset = this->got_page_offset_next_;
  this->got_page_offsets_[value] = got_offset;
  this->got_page_offset_next_ += size/8;
  got->update_got_entry(got_offset, value);
  return got_offset;
}

// Remove lazy-binding stubs for global symbols in this GOT.

template<int size, bool big_endian>
void
Mips_got_info<size, big_endian>::remove_lazy_stubs(
    Target_mips<size, big_endian>* target)
{
  for (typename Got_entry_set::iterator
       p = this->got_entries_.begin();
       p != this->got_entries_.end();
       ++p)
    {
      Mips_got_entry<size, big_endian>* entry = *p;
      if (entry->is_for_global_symbol())
        target->remove_lazy_stub_entry(entry->sym());
    }
}

// Count the number of GOT entries required.

template<int size, bool big_endian>
void
Mips_got_info<size, big_endian>::count_got_entries()
{
  for (typename Got_entry_set::iterator
       p = this->got_entries_.begin();
       p != this->got_entries_.end();
       ++p)
    {
      this->count_got_entry(*p);
    }
}

// Count the number of GOT entries required by ENTRY.  Accumulate the result.

template<int size, bool big_endian>
void
Mips_got_info<size, big_endian>::count_got_entry(
    Mips_got_entry<size, big_endian>* entry)
{
  if (entry->is_tls_entry())
    this->tls_gotno_ += mips_tls_got_entries(entry->tls_type());
  else if (entry->is_for_local_symbol()
           || entry->sym()->global_got_area() == GGA_NONE)
    ++this->local_gotno_;
  else
    ++this->global_gotno_;
}

// Add FROM's GOT entries.

template<int size, bool big_endian>
void
Mips_got_info<size, big_endian>::add_got_entries(
    Mips_got_info<size, big_endian>* from)
{
  for (typename Got_entry_set::iterator
       p = from->got_entries_.begin();
       p != from->got_entries_.end();
       ++p)
    {
      Mips_got_entry<size, big_endian>* entry = *p;
      if (this->got_entries_.find(entry) == this->got_entries_.end())
        {
          Mips_got_entry<size, big_endian>* entry2 =
            new Mips_got_entry<size, big_endian>(*entry);
          this->got_entries_.insert(entry2);
          this->count_got_entry(entry);
        }
    }
}

// Add FROM's GOT page entries.

template<int size, bool big_endian>
void
Mips_got_info<size, big_endian>::add_got_page_entries(
    Mips_got_info<size, big_endian>* from)
{
  for (typename Got_page_entry_set::iterator
       p = from->got_page_entries_.begin();
       p != from->got_page_entries_.end();
       ++p)
    {
      Got_page_entry* entry = *p;
      if (this->got_page_entries_.find(entry) == this->got_page_entries_.end())
        {
          Got_page_entry* entry2 = new Got_page_entry(*entry);
          this->got_page_entries_.insert(entry2);
          this->page_gotno_ += entry->num_pages;
        }
    }
}

// Mips_output_data_got methods.

// Lay out the GOT.  Add local, global and TLS entries.  If GOT is
// larger than 64K, create multi-GOT.

template<int size, bool big_endian>
void
Mips_output_data_got<size, big_endian>::lay_out_got(Layout* layout,
    Symbol_table* symtab, const Input_objects* input_objects)
{
  // Decide which symbols need to go in the global part of the GOT and
  // count the number of reloc-only GOT symbols.
  this->master_got_info_->count_got_symbols(symtab);

  // Count the number of GOT entries.
  this->master_got_info_->count_got_entries();

  unsigned int got_size = this->master_got_info_->got_size();
  if (got_size > Target_mips<size, big_endian>::MIPS_GOT_MAX_SIZE)
    this->lay_out_multi_got(layout, input_objects);
  else
    {
      // Record that all objects use single GOT.
      for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
           p != input_objects->relobj_end();
           ++p)
        {
          Mips_relobj<size, big_endian>* object =
            Mips_relobj<size, big_endian>::as_mips_relobj(*p);
          if (object->get_got_info() != NULL)
            object->set_got_info(this->master_got_info_);
        }

      this->master_got_info_->add_local_entries(this->target_, layout);
      this->master_got_info_->add_global_entries(this->target_, layout,
                                                 /*not used*/-1U);
      this->master_got_info_->add_tls_entries(this->target_, layout);
    }
}

// Create multi-GOT.  For every GOT, add local, global and TLS entries.

template<int size, bool big_endian>
void
Mips_output_data_got<size, big_endian>::lay_out_multi_got(Layout* layout,
    const Input_objects* input_objects)
{
  // Try to merge the GOTs of input objects together, as long as they
  // don't seem to exceed the maximum GOT size, choosing one of them
  // to be the primary GOT.
  this->merge_gots(input_objects);

  // Every symbol that is referenced in a dynamic relocation must be
  // present in the primary GOT.
  this->primary_got_->set_global_gotno(this->master_got_info_->global_gotno());

  // Add GOT entries.
  unsigned int i = 0;
  unsigned int offset = 0;
  Mips_got_info<size, big_endian>* g = this->primary_got_;
  do
    {
      g->set_index(i);
      g->set_offset(offset);

      g->add_local_entries(this->target_, layout);
      if (i == 0)
        g->add_global_entries(this->target_, layout,
                              (this->master_got_info_->global_gotno()
                               - this->master_got_info_->reloc_only_gotno()));
      else
        g->add_global_entries(this->target_, layout, /*not used*/-1U);
      g->add_tls_entries(this->target_, layout);

      // Forbid global symbols in every non-primary GOT from having
      // lazy-binding stubs.
      if (i > 0)
        g->remove_lazy_stubs(this->target_);

      ++i;
      offset += g->got_size();
      g = g->next();
    }
  while (g);
}

// Attempt to merge GOTs of different input objects.  Try to use as much as
// possible of the primary GOT, since it doesn't require explicit dynamic
// relocations, but don't use objects that would reference global symbols
// out of the addressable range.  Failing the primary GOT, attempt to merge
// with the current GOT, or finish the current GOT and then make make the new
// GOT current.

template<int size, bool big_endian>
void
Mips_output_data_got<size, big_endian>::merge_gots(
    const Input_objects* input_objects)
{
  gold_assert(this->primary_got_ == NULL);
  Mips_got_info<size, big_endian>* current = NULL;

  for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
       p != input_objects->relobj_end();
       ++p)
    {
      Mips_relobj<size, big_endian>* object =
        Mips_relobj<size, big_endian>::as_mips_relobj(*p);

      Mips_got_info<size, big_endian>* g = object->get_got_info();
      if (g == NULL)
        continue;

      g->count_got_entries();

      // Work out the number of page, local and TLS entries.
      unsigned int estimate = this->master_got_info_->page_gotno();
      if (estimate > g->page_gotno())
        estimate = g->page_gotno();
      estimate += g->local_gotno() + g->tls_gotno();

      // We place TLS GOT entries after both locals and globals.  The globals
      // for the primary GOT may overflow the normal GOT size limit, so be
      // sure not to merge a GOT which requires TLS with the primary GOT in that
      // case.  This doesn't affect non-primary GOTs.
      estimate += (g->tls_gotno() > 0 ? this->master_got_info_->global_gotno()
                                      : g->global_gotno());

      unsigned int max_count =
        Target_mips<size, big_endian>::MIPS_GOT_MAX_SIZE / (size/8) - 2;
      if (estimate <= max_count)
        {
          // If we don't have a primary GOT, use it as
          // a starting point for the primary GOT.
          if (!this->primary_got_)
            {
              this->primary_got_ = g;
              continue;
            }

          // Try merging with the primary GOT.
          if (this->merge_got_with(g, object, this->primary_got_))
            continue;
        }

      // If we can merge with the last-created GOT, do it.
      if (current && this->merge_got_with(g, object, current))
        continue;

      // Well, we couldn't merge, so create a new GOT.  Don't check if it
      // fits; if it turns out that it doesn't, we'll get relocation
      // overflows anyway.
      g->set_next(current);
      current = g;
    }

  // If we do not find any suitable primary GOT, create an empty one.
  if (this->primary_got_ == NULL)
    this->primary_got_ = new Mips_got_info<size, big_endian>();

  // Link primary GOT with secondary GOTs.
  this->primary_got_->set_next(current);
}

// Consider merging FROM, which is OBJECT's GOT, into TO.  Return false if
// this would lead to overflow, true if they were merged successfully.

template<int size, bool big_endian>
bool
Mips_output_data_got<size, big_endian>::merge_got_with(
    Mips_got_info<size, big_endian>* from,
    Mips_relobj<size, big_endian>* object,
    Mips_got_info<size, big_endian>* to)
{
  // Work out how many page entries we would need for the combined GOT.
  unsigned int estimate = this->master_got_info_->page_gotno();
  if (estimate >= from->page_gotno() + to->page_gotno())
    estimate = from->page_gotno() + to->page_gotno();

  // Conservatively estimate how many local and TLS entries would be needed.
  estimate += from->local_gotno() + to->local_gotno();
  estimate += from->tls_gotno() + to->tls_gotno();

  // If we're merging with the primary got, any TLS relocations will
  // come after the full set of global entries.  Otherwise estimate those
  // conservatively as well.
  if (to == this->primary_got_ && (from->tls_gotno() + to->tls_gotno()) > 0)
    estimate += this->master_got_info_->global_gotno();
  else
    estimate += from->global_gotno() + to->global_gotno();

  // Bail out if the combined GOT might be too big.
  unsigned int max_count =
    Target_mips<size, big_endian>::MIPS_GOT_MAX_SIZE / (size/8) - 2;
  if (estimate > max_count)
    return false;

  // Transfer the object's GOT information from FROM to TO.
  to->add_got_entries(from);
  to->add_got_page_entries(from);

  // Record that OBJECT should use output GOT TO.
  object->set_got_info(to);

  return true;
}

// Write out the GOT.

template<int size, bool big_endian>
void
Mips_output_data_got<size, big_endian>::do_write(Output_file* of)
{
  typedef Unordered_set<Mips_symbol<size>*, Mips_symbol_hash<size> >
      Mips_stubs_entry_set;

  // Call parent to write out GOT.
  Output_data_got<size, big_endian>::do_write(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);

  // Needed for fixing values of .got section.
  this->got_view_ = oview;

  // Write lazy stub addresses.
  for (typename Mips_stubs_entry_set::iterator
       p = this->master_got_info_->global_got_symbols().begin();
       p != this->master_got_info_->global_got_symbols().end();
       ++p)
    {
      Mips_symbol<size>* mips_sym = *p;
      if (mips_sym->has_lazy_stub())
        {
          Valtype* wv = reinterpret_cast<Valtype*>(
            oview + this->get_primary_got_offset(mips_sym));
          Valtype value =
            this->target_->mips_stubs_section()->stub_address(mips_sym);
          elfcpp::Swap<size, big_endian>::writeval(wv, value);
        }
    }

  // Add +1 to GGA_NONE nonzero MIPS16 and microMIPS entries.
  for (typename Mips_stubs_entry_set::iterator
       p = this->master_got_info_->global_got_symbols().begin();
       p != this->master_got_info_->global_got_symbols().end();
       ++p)
    {
      Mips_symbol<size>* mips_sym = *p;
      if (!this->multi_got()
          && (mips_sym->is_mips16() || mips_sym->is_micromips())
          && mips_sym->global_got_area() == GGA_NONE
          && mips_sym->has_got_offset(GOT_TYPE_STANDARD))
        {
          Valtype* wv = reinterpret_cast<Valtype*>(
            oview + mips_sym->got_offset(GOT_TYPE_STANDARD));
          Valtype value = elfcpp::Swap<size, big_endian>::readval(wv);
          if (value != 0)
            {
              value |= 1;
              elfcpp::Swap<size, big_endian>::writeval(wv, value);
            }
        }
    }

  if (!this->secondary_got_relocs_.empty())
    {
      // Fixup for the secondary GOT R_MIPS_REL32 relocs.  For global
      // secondary GOT entries with non-zero initial value copy the value
      // to the corresponding primary GOT entry, and set the secondary GOT
      // entry to zero.
      // TODO(sasa): This is workaround.  It needs to be investigated further.

      for (size_t i = 0; i < this->secondary_got_relocs_.size(); ++i)
        {
          Static_reloc& reloc(this->secondary_got_relocs_[i]);
          if (reloc.symbol_is_global())
            {
              Mips_symbol<size>* gsym = reloc.symbol();
              gold_assert(gsym != NULL);

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

              // Find primary GOT entry.
              Valtype* wv_prim = reinterpret_cast<Valtype*>(
                oview + this->get_primary_got_offset(gsym));

              // Find secondary GOT entry.
              Valtype* wv_sec = reinterpret_cast<Valtype*>(oview + got_offset);

              Valtype value = elfcpp::Swap<size, big_endian>::readval(wv_sec);
              if (value != 0)
                {
                  elfcpp::Swap<size, big_endian>::writeval(wv_prim, value);
                  elfcpp::Swap<size, big_endian>::writeval(wv_sec, 0);
                  gsym->set_applied_secondary_got_fixup();
                }
            }
        }

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

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

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

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

      Mips_address value;
      if (!reloc.symbol_is_global())
        {
          Sized_relobj_file<size, big_endian>* object = reloc.relobj();
          const Symbol_value<size>* psymval =
            object->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 Mips_symbol<size>* gsym = reloc.symbol();
          gold_assert(gsym != NULL);

          // 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())
            value = gsym->value();
          else
            value = 0;
        }

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

      Valtype* wv = reinterpret_cast<Valtype*>(oview + got_offset);
      Valtype x;

      switch (reloc.r_type())
        {
        case elfcpp::R_MIPS_TLS_DTPMOD32:
        case elfcpp::R_MIPS_TLS_DTPMOD64:
          x = value;
          break;
        case elfcpp::R_MIPS_TLS_DTPREL32:
        case elfcpp::R_MIPS_TLS_DTPREL64:
          x = value - elfcpp::DTP_OFFSET;
          break;
        case elfcpp::R_MIPS_TLS_TPREL32:
        case elfcpp::R_MIPS_TLS_TPREL64:
          x = value - elfcpp::TP_OFFSET;
          break;
        default:
          gold_unreachable();
          break;
        }

      elfcpp::Swap<size, big_endian>::writeval(wv, x);
    }

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

// Mips_relobj methods.

// Count the local symbols.  The Mips backend needs to know if a symbol
// is a MIPS16 or microMIPS function or not.  For global symbols, it is easy
// because the Symbol object keeps the ELF symbol type and st_other field.
// 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 MIPS16 and microMIPS functions.  This is not the most efficient way but
// I do not want to slow down other ports by calling a per symbol target hook
// inside Sized_relobj_file<size, big_endian>::do_count_local_symbols.

template<int size, bool big_endian>
void
Mips_relobj<size, big_endian>::do_count_local_symbols(
    Stringpool_template<char>* pool,
    Stringpool_template<char>* dynpool)
{
  // Ask parent to count the local symbols.
  Sized_relobj_file<size, big_endian>::do_count_local_symbols(pool, dynpool);
  const unsigned int loccount = this->local_symbol_count();
  if (loccount == 0)
    return;

  // Initialize the mips16 and micromips function bit-vector.
  this->local_symbol_is_mips16_.resize(loccount, false);
  this->local_symbol_is_micromips_.resize(loccount, false);

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

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

  // Loop over the local symbols and mark any MIPS16 or microMIPS local symbols.

  // Skip the first dummy symbol.
  psyms += sym_size;
  for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size)
    {
      elfcpp::Sym<size, big_endian> sym(psyms);
      unsigned char st_other = sym.get_st_other();
      this->local_symbol_is_mips16_[i] = elfcpp::elf_st_is_mips16(st_other);
      this->local_symbol_is_micromips_[i] =
        elfcpp::elf_st_is_micromips(st_other);
    }
}

// Read the symbol information.

template<int size, bool big_endian>
void
Mips_relobj<size, big_endian>::do_read_symbols(Read_symbols_data* sd)
{
  // Call parent class to read symbol information.
  this->base_read_symbols(sd);

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

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

  // Get the section names.
  const unsigned char* pnamesu = sd->section_names->data();
  const char* pnames = reinterpret_cast<const char*>(pnamesu);

  // Initialize the mips16 stub section bit-vectors.
  this->section_is_mips16_fn_stub_.resize(this->shnum(), false);
  this->section_is_mips16_call_stub_.resize(this->shnum(), false);
  this->section_is_mips16_call_fp_stub_.resize(this->shnum(), false);

  const size_t shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
  const unsigned char* pshdrs = sd->section_headers->data();
  const unsigned char* ps = pshdrs + shdr_size;
  bool must_merge_processor_specific_data = false;
  for (unsigned int i = 1; i < this->shnum(); ++i, ps += shdr_size)
    {
      elfcpp::Shdr<size, 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 data from such an object.
      if (shdr.get_sh_type() == elfcpp::SHT_SYMTAB)
        {
          // Symbol table is not empty.
          const typename elfcpp::Elf_types<size>::Elf_WXword sym_size =
            elfcpp::Elf_sizes<size>::sym_size;
          if (shdr.get_sh_size() > sym_size)
            must_merge_processor_specific_data = 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_processor_specific_data = true;

      if (shdr.get_sh_type() == elfcpp::SHT_MIPS_REGINFO)
        {
          this->has_reginfo_section_ = true;
          // Read the gp value that was used to create this object.  We need the
          // gp value while processing relocs.  The .reginfo section is not used
          // in the 64-bit MIPS ELF ABI.
          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->gp_ = elfcpp::Swap<size, big_endian>::readval(view + 20);

          // Read the rest of .reginfo.
          this->gprmask_ = elfcpp::Swap<size, big_endian>::readval(view);
          this->cprmask1_ = elfcpp::Swap<size, big_endian>::readval(view + 4);
          this->cprmask2_ = elfcpp::Swap<size, big_endian>::readval(view + 8);
          this->cprmask3_ = elfcpp::Swap<size, big_endian>::readval(view + 12);
          this->cprmask4_ = elfcpp::Swap<size, big_endian>::readval(view + 16);
        }

      if (shdr.get_sh_type() == elfcpp::SHT_GNU_ATTRIBUTES)
        {
          gold_assert(this->attributes_section_data_ == NULL);
          section_offset_type section_offset = shdr.get_sh_offset();
          section_size_type section_size =
            convert_to_section_size_type(shdr.get_sh_size());
          const unsigned char* view =
            this->get_view(section_offset, section_size, true, false);
          this->attributes_section_data_ =
            new Attributes_section_data(view, section_size);
        }

      if (shdr.get_sh_type() == elfcpp::SHT_MIPS_ABIFLAGS)
        {
          gold_assert(this->abiflags_ == 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->abiflags_ = new Mips_abiflags<big_endian>();

          this->abiflags_->version =
            elfcpp::Swap<16, big_endian>::readval(view);
          if (this->abiflags_->version != 0)
            {
              gold_error(_("%s: .MIPS.abiflags section has "
                           "unsupported version %u"),
                         this->name().c_str(),
                         this->abiflags_->version);
              break;
            }
          this->abiflags_->isa_level =
            elfcpp::Swap<8, big_endian>::readval(view + 2);
          this->abiflags_->isa_rev =
            elfcpp::Swap<8, big_endian>::readval(view + 3);
          this->abiflags_->gpr_size =
            elfcpp::Swap<8, big_endian>::readval(view + 4);
          this->abiflags_->cpr1_size =
            elfcpp::Swap<8, big_endian>::readval(view + 5);
          this->abiflags_->cpr2_size =
            elfcpp::Swap<8, big_endian>::readval(view + 6);
          this->abiflags_->fp_abi =
            elfcpp::Swap<8, big_endian>::readval(view + 7);
          this->abiflags_->isa_ext =
            elfcpp::Swap<32, big_endian>::readval(view + 8);
          this->abiflags_->ases =
            elfcpp::Swap<32, big_endian>::readval(view + 12);
          this->abiflags_->flags1 =
            elfcpp::Swap<32, big_endian>::readval(view + 16);
          this->abiflags_->flags2 =
            elfcpp::Swap<32, big_endian>::readval(view + 20);
        }

      // In the 64-bit ABI, .MIPS.options section holds register information.
      // A SHT_MIPS_OPTIONS section contains a series of options, each of which
      // starts with this header:
      //
      // typedef struct
      // {
      //   // Type of option.
      //   unsigned char kind[1];
      //   // Size of option descriptor, including header.
      //   unsigned char size[1];
      //   // Section index of affected section, or 0 for global option.
      //   unsigned char section[2];
      //   // Information specific to this kind of option.
      //   unsigned char info[4];
      // };
      //
      // For a SHT_MIPS_OPTIONS section, look for a ODK_REGINFO entry, and set
      // the gp value based on what we find.  We may see both SHT_MIPS_REGINFO
      // and SHT_MIPS_OPTIONS/ODK_REGINFO; in that case, they should agree.

      if (shdr.get_sh_type() == elfcpp::SHT_MIPS_OPTIONS)
        {
          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);
          const unsigned char* end = view + section_size;

          while (view + 8 <= end)
            {
              unsigned char kind = elfcpp::Swap<8, big_endian>::readval(view);
              unsigned char sz = elfcpp::Swap<8, big_endian>::readval(view + 1);
              if (sz < 8)
                {
                  gold_error(_("%s: Warning: bad `%s' option size %u smaller "
                               "than its header"),
                             this->name().c_str(),
                             this->mips_elf_options_section_name(), sz);
                  break;
                }

              if (this->is_n64() && kind == elfcpp::ODK_REGINFO)
                {
                  // In the 64 bit ABI, an ODK_REGINFO option is the following
                  // structure.  The info field of the options header is not
                  // used.
                  //
                  // typedef struct
                  // {
                  //   // Mask of general purpose registers used.
                  //   unsigned char ri_gprmask[4];
                  //   // Padding.
                  //   unsigned char ri_pad[4];
                  //   // Mask of co-processor registers used.
                  //   unsigned char ri_cprmask[4][4];
                  //   // GP register value for this object file.
                  //   unsigned char ri_gp_value[8];
                  // };

                  this->gp_ = elfcpp::Swap<size, big_endian>::readval(view
                                                                      + 32);
                }
              else if (kind == elfcpp::ODK_REGINFO)
                {
                  // In the 32 bit ABI, an ODK_REGINFO option is the following
                  // structure.  The info field of the options header is not
                  // used.  The same structure is used in .reginfo section.
                  //
                  // typedef struct
                  // {
                  //   unsigned char ri_gprmask[4];
                  //   unsigned char ri_cprmask[4][4];
                  //   unsigned char ri_gp_value[4];
                  // };

                  this->gp_ = elfcpp::Swap<size, big_endian>::readval(view
                                                                      + 28);
                }
              view += sz;
            }
        }

      const char* name = pnames + shdr.get_sh_name();
      this->section_is_mips16_fn_stub_[i] = is_prefix_of(".mips16.fn", name);
      this->section_is_mips16_call_stub_[i] =
        is_prefix_of(".mips16.call.", name);
      this->section_is_mips16_call_fp_stub_[i] =
        is_prefix_of(".mips16.call.fp.", name);

      if (strcmp(name, ".pdr") == 0)
        {
          gold_assert(this->pdr_shndx_ == -1U);
          this->pdr_shndx_ = i;
        }
    }

  // This is rare.
  if (!must_merge_processor_specific_data)
    this->merge_processor_specific_data_ = false;
}

// Discard MIPS16 stub secions that are not needed.

template<int size, bool big_endian>
void
Mips_relobj<size, big_endian>::discard_mips16_stub_sections(Symbol_table* symtab)
{
  for (typename Mips16_stubs_int_map::const_iterator
       it = this->mips16_stub_sections_.begin();
       it != this->mips16_stub_sections_.end(); ++it)
    {
      Mips16_stub_section<size, big_endian>* stub_section = it->second;
      if (!stub_section->is_target_found())
        {
          gold_error(_("no relocation found in mips16 stub section '%s'"),
                     stub_section->object()
                       ->section_name(stub_section->shndx()).c_str());
        }

      bool discard = false;
      if (stub_section->is_for_local_function())
        {
          if (stub_section->is_fn_stub())
            {
              // This stub is for a local symbol.  This stub will only
              // be needed if there is some relocation in this object,
              // other than a 16 bit function call, which refers to this
              // symbol.
              if (!this->has_local_non_16bit_call_relocs(stub_section->r_sym()))
                discard = true;
              else
                this->add_local_mips16_fn_stub(stub_section);
            }
          else
            {
              // This stub is for a local symbol.  This stub will only
              // be needed if there is some relocation (R_MIPS16_26) in
              // this object that refers to this symbol.
              gold_assert(stub_section->is_call_stub()
                          || stub_section->is_call_fp_stub());
              if (!this->has_local_16bit_call_relocs(stub_section->r_sym()))
                discard = true;
              else
                this->add_local_mips16_call_stub(stub_section);
            }
        }
      else
        {
          Mips_symbol<size>* gsym = stub_section->gsym();
          if (stub_section->is_fn_stub())
            {
              if (gsym->has_mips16_fn_stub())
                // We already have a stub for this function.
                discard = true;
              else
                {
                  gsym->set_mips16_fn_stub(stub_section);
                  if (gsym->should_add_dynsym_entry(symtab))
                    {
                      // If we have a MIPS16 function with a stub, the
                      // dynamic symbol must refer to the stub, since only
                      // the stub uses the standard calling conventions.
                      gsym->set_need_fn_stub();
                      if (gsym->is_from_dynobj())
                        gsym->set_needs_dynsym_value();
                    }
                }
              if (!gsym->need_fn_stub())
                discard = true;
            }
          else if (stub_section->is_call_stub())
            {
              if (gsym->is_mips16())
                // We don't need the call_stub; this is a 16 bit
                // function, so calls from other 16 bit functions are
                // OK.
                discard = true;
              else if (gsym->has_mips16_call_stub())
                // We already have a stub for this function.
                discard = true;
              else
                gsym->set_mips16_call_stub(stub_section);
            }
          else
            {
              gold_assert(stub_section->is_call_fp_stub());
              if (gsym->is_mips16())
                // We don't need the call_stub; this is a 16 bit
                // function, so calls from other 16 bit functions are
                // OK.
                discard = true;
              else if (gsym->has_mips16_call_fp_stub())
                // We already have a stub for this function.
                discard = true;
              else
                gsym->set_mips16_call_fp_stub(stub_section);
            }
        }
      if (discard)
        this->set_output_section(stub_section->shndx(), NULL);
   }
}

// Mips_output_data_la25_stub methods.

// Template for standard LA25 stub.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_la25_stub<size, big_endian>::la25_stub_entry[] =
{
  0x3c190000,           // lui $25,%hi(func)
  0x08000000,           // j func
  0x27390000,           // add $25,$25,%lo(func)
  0x00000000            // nop
};

// Template for microMIPS LA25 stub.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_la25_stub<size, big_endian>::la25_stub_micromips_entry[] =
{
  0x41b9, 0x0000,       // lui t9,%hi(func)
  0xd400, 0x0000,       // j func
  0x3339, 0x0000,       // addiu t9,t9,%lo(func)
  0x0000, 0x0000        // nop
};

// Create la25 stub for a symbol.

template<int size, bool big_endian>
void
Mips_output_data_la25_stub<size, big_endian>::create_la25_stub(
    Symbol_table* symtab, Target_mips<size, big_endian>* target,
    Mips_symbol<size>* gsym)
{
  if (!gsym->has_la25_stub())
    {
      gsym->set_la25_stub_offset(this->symbols_.size() * 16);
      this->symbols_.push_back(gsym);
      this->create_stub_symbol(gsym, symtab, target, 16);
    }
}

// Create a symbol for SYM stub's value and size, to help make the disassembly
// easier to read.

template<int size, bool big_endian>
void
Mips_output_data_la25_stub<size, big_endian>::create_stub_symbol(
    Mips_symbol<size>* sym, Symbol_table* symtab,
    Target_mips<size, big_endian>* target, uint64_t symsize)
{
  std::string name(".pic.");
  name += sym->name();

  unsigned int offset = sym->la25_stub_offset();
  if (sym->is_micromips())
    offset |= 1;

  // Make it a local function.
  Symbol* new_sym = symtab->define_in_output_data(name.c_str(), NULL,
                                      Symbol_table::PREDEFINED,
                                      target->la25_stub_section(),
                                      offset, symsize, elfcpp::STT_FUNC,
                                      elfcpp::STB_LOCAL,
                                      elfcpp::STV_DEFAULT, 0,
                                      false, false);
  new_sym->set_is_forced_local();
}

// Write out la25 stubs.  This uses the hand-coded instructions above,
// and adjusts them as needed.

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

  for (typename std::vector<Mips_symbol<size>*>::iterator
       p = this->symbols_.begin();
       p != this->symbols_.end();
       ++p)
    {
      Mips_symbol<size>* sym = *p;
      unsigned char* pov = oview + sym->la25_stub_offset();

      Mips_address target = sym->value();
      if (!sym->is_micromips())
        {
          elfcpp::Swap<32, big_endian>::writeval(pov,
              la25_stub_entry[0] | (((target + 0x8000) >> 16) & 0xffff));
          elfcpp::Swap<32, big_endian>::writeval(pov + 4,
              la25_stub_entry[1] | ((target >> 2) & 0x3ffffff));
          elfcpp::Swap<32, big_endian>::writeval(pov + 8,
              la25_stub_entry[2] | (target & 0xffff));
          elfcpp::Swap<32, big_endian>::writeval(pov + 12, la25_stub_entry[3]);
        }
      else
        {
          target |= 1;
          // First stub instruction.  Paste high 16-bits of the target.
          elfcpp::Swap<16, big_endian>::writeval(pov,
                                                 la25_stub_micromips_entry[0]);
          elfcpp::Swap<16, big_endian>::writeval(pov + 2,
              ((target + 0x8000) >> 16) & 0xffff);
          // Second stub instruction.  Paste low 26-bits of the target, shifted
          // right by 1.
          elfcpp::Swap<16, big_endian>::writeval(pov + 4,
              la25_stub_micromips_entry[2] | ((target >> 17) & 0x3ff));
          elfcpp::Swap<16, big_endian>::writeval(pov + 6,
              la25_stub_micromips_entry[3] | ((target >> 1) & 0xffff));
          // Third stub instruction.  Paste low 16-bits of the target.
          elfcpp::Swap<16, big_endian>::writeval(pov + 8,
                                                 la25_stub_micromips_entry[4]);
          elfcpp::Swap<16, big_endian>::writeval(pov + 10, target & 0xffff);
          // Fourth stub instruction.
          elfcpp::Swap<16, big_endian>::writeval(pov + 12,
                                                 la25_stub_micromips_entry[6]);
          elfcpp::Swap<16, big_endian>::writeval(pov + 14,
                                                 la25_stub_micromips_entry[7]);
        }
    }

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

// Mips_output_data_plt methods.

// The format of the first PLT entry in an O32 executable.
template<int size, bool big_endian>
const uint32_t Mips_output_data_plt<size, big_endian>::plt0_entry_o32[] =
{
  0x3c1c0000,         // lui $28, %hi(&GOTPLT[0])
  0x8f990000,         // lw $25, %lo(&GOTPLT[0])($28)
  0x279c0000,         // addiu $28, $28, %lo(&GOTPLT[0])
  0x031cc023,         // subu $24, $24, $28
  0x03e07825,         // or $15, $31, zero
  0x0018c082,         // srl $24, $24, 2
  0x0320f809,         // jalr $25
  0x2718fffe          // subu $24, $24, 2
};

// The format of the first PLT entry in an N32 executable.  Different
// because gp ($28) is not available; we use t2 ($14) instead.
template<int size, bool big_endian>
const uint32_t Mips_output_data_plt<size, big_endian>::plt0_entry_n32[] =
{
  0x3c0e0000,         // lui $14, %hi(&GOTPLT[0])
  0x8dd90000,         // lw $25, %lo(&GOTPLT[0])($14)
  0x25ce0000,         // addiu $14, $14, %lo(&GOTPLT[0])
  0x030ec023,         // subu $24, $24, $14
  0x03e07825,         // or $15, $31, zero
  0x0018c082,         // srl $24, $24, 2
  0x0320f809,         // jalr $25
  0x2718fffe          // subu $24, $24, 2
};

// The format of the first PLT entry in an N64 executable.  Different
// from N32 because of the increased size of GOT entries.
template<int size, bool big_endian>
const uint32_t Mips_output_data_plt<size, big_endian>::plt0_entry_n64[] =
{
  0x3c0e0000,         // lui $14, %hi(&GOTPLT[0])
  0xddd90000,         // ld $25, %lo(&GOTPLT[0])($14)
  0x25ce0000,         // addiu $14, $14, %lo(&GOTPLT[0])
  0x030ec023,         // subu $24, $24, $14
  0x03e07825,         // or $15, $31, zero
  0x0018c0c2,         // srl $24, $24, 3
  0x0320f809,         // jalr $25
  0x2718fffe          // subu $24, $24, 2
};

// The format of the microMIPS first PLT entry in an O32 executable.
// We rely on v0 ($2) rather than t8 ($24) to contain the address
// of the GOTPLT entry handled, so this stub may only be used when
// all the subsequent PLT entries are microMIPS code too.
//
// The trailing NOP is for alignment and correct disassembly only.
template<int size, bool big_endian>
const uint32_t Mips_output_data_plt<size, big_endian>::
plt0_entry_micromips_o32[] =
{
  0x7980, 0x0000,      // addiupc $3, (&GOTPLT[0]) - .
  0xff23, 0x0000,      // lw $25, 0($3)
  0x0535,              // subu $2, $2, $3
  0x2525,              // srl $2, $2, 2
  0x3302, 0xfffe,      // subu $24, $2, 2
  0x0dff,              // move $15, $31
  0x45f9,              // jalrs $25
  0x0f83,              // move $28, $3
  0x0c00               // nop
};

// The format of the microMIPS first PLT entry in an O32 executable
// in the insn32 mode.
template<int size, bool big_endian>
const uint32_t Mips_output_data_plt<size, big_endian>::
plt0_entry_micromips32_o32[] =
{
  0x41bc, 0x0000,      // lui $28, %hi(&GOTPLT[0])
  0xff3c, 0x0000,      // lw $25, %lo(&GOTPLT[0])($28)
  0x339c, 0x0000,      // addiu $28, $28, %lo(&GOTPLT[0])
  0x0398, 0xc1d0,      // subu $24, $24, $28
  0x001f, 0x7a90,      // or $15, $31, zero
  0x0318, 0x1040,      // srl $24, $24, 2
  0x03f9, 0x0f3c,      // jalr $25
  0x3318, 0xfffe       // subu $24, $24, 2
};

// The format of subsequent standard entries in the PLT.
template<int size, bool big_endian>
const uint32_t Mips_output_data_plt<size, big_endian>::plt_entry[] =
{
  0x3c0f0000,           // lui $15, %hi(.got.plt entry)
  0x01f90000,           // l[wd] $25, %lo(.got.plt entry)($15)
  0x03200008,           // jr $25
  0x25f80000            // addiu $24, $15, %lo(.got.plt entry)
};

// The format of subsequent R6 PLT entries.
template<int size, bool big_endian>
const uint32_t Mips_output_data_plt<size, big_endian>::plt_entry_r6[] =
{
  0x3c0f0000,           // lui $15, %hi(.got.plt entry)
  0x01f90000,           // l[wd] $25, %lo(.got.plt entry)($15)
  0x03200009,           // jr $25
  0x25f80000            // addiu $24, $15, %lo(.got.plt entry)
};

// The format of subsequent MIPS16 o32 PLT entries.  We use v1 ($3) as a
// temporary because t8 ($24) and t9 ($25) are not directly addressable.
// Note that this differs from the GNU ld which uses both v0 ($2) and v1 ($3).
// We cannot use v0 because MIPS16 call stubs from the CS toolchain expect
// target function address in register v0.
template<int size, bool big_endian>
const uint32_t Mips_output_data_plt<size, big_endian>::plt_entry_mips16_o32[] =
{
  0xb303,              // lw $3, 12($pc)
  0x651b,              // move $24, $3
  0x9b60,              // lw $3, 0($3)
  0xeb00,              // jr $3
  0x653b,              // move $25, $3
  0x6500,              // nop
  0x0000, 0x0000       // .word (.got.plt entry)
};

// The format of subsequent microMIPS o32 PLT entries.  We use v0 ($2)
// as a temporary because t8 ($24) is not addressable with ADDIUPC.
template<int size, bool big_endian>
const uint32_t Mips_output_data_plt<size, big_endian>::
plt_entry_micromips_o32[] =
{
  0x7900, 0x0000,      // addiupc $2, (.got.plt entry) - .
  0xff22, 0x0000,      // lw $25, 0($2)
  0x4599,              // jr $25
  0x0f02               // move $24, $2
};

// The format of subsequent microMIPS o32 PLT entries in the insn32 mode.
template<int size, bool big_endian>
const uint32_t Mips_output_data_plt<size, big_endian>::
plt_entry_micromips32_o32[] =
{
  0x41af, 0x0000,      // lui $15, %hi(.got.plt entry)
  0xff2f, 0x0000,      // lw $25, %lo(.got.plt entry)($15)
  0x0019, 0x0f3c,      // jr $25
  0x330f, 0x0000       // addiu $24, $15, %lo(.got.plt entry)
};

// Add an entry to the PLT for a symbol referenced by r_type relocation.

template<int size, bool big_endian>
void
Mips_output_data_plt<size, big_endian>::add_entry(Mips_symbol<size>* gsym,
                                                  unsigned int r_type)
{
  gold_assert(!gsym->has_plt_offset());

  // Final PLT offset for a symbol will be set in method set_plt_offsets().
  gsym->set_plt_offset(this->entry_count() * sizeof(plt_entry)
                       + sizeof(plt0_entry_o32));
  this->symbols_.push_back(gsym);

  // Record whether the relocation requires a standard MIPS
  // or a compressed code entry.
  if (jal_reloc(r_type))
   {
     if (r_type == elfcpp::R_MIPS_26)
       gsym->set_needs_mips_plt(true);
     else
       gsym->set_needs_comp_plt(true);
   }

  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 + size/8);

  gsym->set_needs_dynsym_entry();
  this->rel_->add_global(gsym, elfcpp::R_MIPS_JUMP_SLOT, this->got_plt_,
                         got_offset);
}

// Set final PLT offsets.  For each symbol, determine whether standard or
// compressed (MIPS16 or microMIPS) PLT entry is used.

template<int size, bool big_endian>
void
Mips_output_data_plt<size, big_endian>::set_plt_offsets()
{
  // The sizes of individual PLT entries.
  unsigned int plt_mips_entry_size = this->standard_plt_entry_size();
  unsigned int plt_comp_entry_size = (!this->target_->is_output_newabi()
                                      ? this->compressed_plt_entry_size() : 0);

  for (typename std::vector<Mips_symbol<size>*>::const_iterator
       p = this->symbols_.begin(); p != this->symbols_.end(); ++p)
    {
      Mips_symbol<size>* mips_sym = *p;

      // There are no defined MIPS16 or microMIPS PLT entries for n32 or n64,
      // so always use a standard entry there.
      //
      // If the symbol has a MIPS16 call stub and gets a PLT entry, then
      // all MIPS16 calls will go via that stub, and there is no benefit
      // to having a MIPS16 entry.  And in the case of call_stub a
      // standard entry actually has to be used as the stub ends with a J
      // instruction.
      if (this->target_->is_output_newabi()
          || mips_sym->has_mips16_call_stub()
          || mips_sym->has_mips16_call_fp_stub())
        {
          mips_sym->set_needs_mips_plt(true);
          mips_sym->set_needs_comp_plt(false);
        }

      // Otherwise, if there are no direct calls to the function, we
      // have a free choice of whether to use standard or compressed
      // entries.  Prefer microMIPS entries if the object is known to
      // contain microMIPS code, so that it becomes possible to create
      // pure microMIPS binaries.  Prefer standard entries otherwise,
      // because MIPS16 ones are no smaller and are usually slower.
      if (!mips_sym->needs_mips_plt() && !mips_sym->needs_comp_plt())
        {
          if (this->target_->is_output_micromips())
            mips_sym->set_needs_comp_plt(true);
          else
            mips_sym->set_needs_mips_plt(true);
        }

      if (mips_sym->needs_mips_plt())
        {
          mips_sym->set_mips_plt_offset(this->plt_mips_offset_);
          this->plt_mips_offset_ += plt_mips_entry_size;
        }
      if (mips_sym->needs_comp_plt())
        {
          mips_sym->set_comp_plt_offset(this->plt_comp_offset_);
          this->plt_comp_offset_ += plt_comp_entry_size;
        }
    }

    // Figure out the size of the PLT header if we know that we are using it.
    if (this->plt_mips_offset_ + this->plt_comp_offset_ != 0)
      this->plt_header_size_ = this->get_plt_header_size();
}

// Write out the PLT.  This uses the hand-coded instructions above,
// and adjusts them as needed.

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

  const off_t gotplt_file_offset = this->got_plt_->offset();
  const section_size_type gotplt_size =
    convert_to_section_size_type(this->got_plt_->data_size());
  unsigned char* const gotplt_view = of->get_output_view(gotplt_file_offset,
                                                         gotplt_size);
  unsigned char* pov = oview;

  Mips_address plt_address = this->address();

  // Calculate the address of .got.plt.
  Mips_address gotplt_addr = this->got_plt_->address();
  Mips_address gotplt_addr_high = ((gotplt_addr + 0x8000) >> 16) & 0xffff;
  Mips_address gotplt_addr_low = gotplt_addr & 0xffff;

  // The PLT sequence is not safe for N64 if .got.plt's address can
  // not be loaded in two instructions.
  gold_assert((gotplt_addr & ~(Mips_address) 0x7fffffff) == 0
              || ~(gotplt_addr | 0x7fffffff) == 0);

  // Write the PLT header.
  const uint32_t* plt0_entry = this->get_plt_header_entry();
  if (plt0_entry == plt0_entry_micromips_o32)
    {
      // Write microMIPS PLT header.
      gold_assert(gotplt_addr % 4 == 0);

      Mips_address gotpc_offset = gotplt_addr - ((plt_address | 3) ^ 3);

      // ADDIUPC has a span of +/-16MB, check we're in range.
      if (gotpc_offset + 0x1000000 >= 0x2000000)
       {
         gold_error(_(".got.plt offset of %ld from .plt beyond the range of "
                    "ADDIUPC"), (long)gotpc_offset);
         return;
       }

      elfcpp::Swap<16, big_endian>::writeval(pov,
                 plt0_entry[0] | ((gotpc_offset >> 18) & 0x7f));
      elfcpp::Swap<16, big_endian>::writeval(pov + 2,
                                             (gotpc_offset >> 2) & 0xffff);
      pov += 4;
      for (unsigned int i = 2;
           i < (sizeof(plt0_entry_micromips_o32)
                / sizeof(plt0_entry_micromips_o32[0]));
           i++)
        {
          elfcpp::Swap<16, big_endian>::writeval(pov, plt0_entry[i]);
          pov += 2;
        }
    }
  else if (plt0_entry == plt0_entry_micromips32_o32)
    {
      // Write microMIPS PLT header in insn32 mode.
      elfcpp::Swap<16, big_endian>::writeval(pov, plt0_entry[0]);
      elfcpp::Swap<16, big_endian>::writeval(pov + 2, gotplt_addr_high);
      elfcpp::Swap<16, big_endian>::writeval(pov + 4, plt0_entry[2]);
      elfcpp::Swap<16, big_endian>::writeval(pov + 6, gotplt_addr_low);
      elfcpp::Swap<16, big_endian>::writeval(pov + 8, plt0_entry[4]);
      elfcpp::Swap<16, big_endian>::writeval(pov + 10, gotplt_addr_low);
      pov += 12;
      for (unsigned int i = 6;
           i < (sizeof(plt0_entry_micromips32_o32)
                / sizeof(plt0_entry_micromips32_o32[0]));
           i++)
        {
          elfcpp::Swap<16, big_endian>::writeval(pov, plt0_entry[i]);
          pov += 2;
        }
    }
  else
    {
      // Write standard PLT header.
      elfcpp::Swap<32, big_endian>::writeval(pov,
                                             plt0_entry[0] | gotplt_addr_high);
      elfcpp::Swap<32, big_endian>::writeval(pov + 4,
                                             plt0_entry[1] | gotplt_addr_low);
      elfcpp::Swap<32, big_endian>::writeval(pov + 8,
                                             plt0_entry[2] | gotplt_addr_low);
      pov += 12;
      for (int i = 3; i < 8; i++)
        {
          elfcpp::Swap<32, big_endian>::writeval(pov, plt0_entry[i]);
          pov += 4;
        }
    }


  unsigned char* gotplt_pov = gotplt_view;
  unsigned int got_entry_size = size/8; // TODO(sasa): MIPS_ELF_GOT_SIZE

  // The first two entries in .got.plt are reserved.
  elfcpp::Swap<size, big_endian>::writeval(gotplt_pov, 0);
  elfcpp::Swap<size, big_endian>::writeval(gotplt_pov + got_entry_size, 0);

  unsigned int gotplt_offset = 2 * got_entry_size;
  gotplt_pov += 2 * got_entry_size;

  // Calculate the address of the PLT header.
  Mips_address header_address = (plt_address
                                 + (this->is_plt_header_compressed() ? 1 : 0));

  // Initialize compressed PLT area view.
  unsigned char* pov2 = pov + this->plt_mips_offset_;

  // Write the PLT entries.
  for (typename std::vector<Mips_symbol<size>*>::const_iterator
       p = this->symbols_.begin();
       p != this->symbols_.end();
       ++p, gotplt_pov += got_entry_size, gotplt_offset += got_entry_size)
    {
      Mips_symbol<size>* mips_sym = *p;

      // Calculate the address of the .got.plt entry.
      uint32_t gotplt_entry_addr = (gotplt_addr + gotplt_offset);
      uint32_t gotplt_entry_addr_hi = (((gotplt_entry_addr + 0x8000) >> 16)
                                       & 0xffff);
      uint32_t gotplt_entry_addr_lo = gotplt_entry_addr & 0xffff;

      // Initially point the .got.plt entry at the PLT header.
      if (this->target_->is_output_n64())
        elfcpp::Swap<64, big_endian>::writeval(gotplt_pov, header_address);
      else
        elfcpp::Swap<32, big_endian>::writeval(gotplt_pov, header_address);

      // Now handle the PLT itself.  First the standard entry.
      if (mips_sym->has_mips_plt_offset())
        {
          // Pick the load opcode (LW or LD).
          uint64_t load = this->target_->is_output_n64() ? 0xdc000000
                                                         : 0x8c000000;

          const uint32_t* entry = this->target_->is_output_r6() ? plt_entry_r6
                                                                : plt_entry;

          // Fill in the PLT entry itself.
          elfcpp::Swap<32, big_endian>::writeval(pov,
              entry[0] | gotplt_entry_addr_hi);
          elfcpp::Swap<32, big_endian>::writeval(pov + 4,
              entry[1] | gotplt_entry_addr_lo | load);
          elfcpp::Swap<32, big_endian>::writeval(pov + 8, entry[2]);
          elfcpp::Swap<32, big_endian>::writeval(pov + 12,
              entry[3] | gotplt_entry_addr_lo);
          pov += 16;
        }

      // Now the compressed entry.  They come after any standard ones.
      if (mips_sym->has_comp_plt_offset())
        {
          if (!this->target_->is_output_micromips())
            {
              // Write MIPS16 PLT entry.
              const uint32_t* plt_entry = plt_entry_mips16_o32;

              elfcpp::Swap<16, big_endian>::writeval(pov2, plt_entry[0]);
              elfcpp::Swap<16, big_endian>::writeval(pov2 + 2, plt_entry[1]);
              elfcpp::Swap<16, big_endian>::writeval(pov2 + 4, plt_entry[2]);
              elfcpp::Swap<16, big_endian>::writeval(pov2 + 6, plt_entry[3]);
              elfcpp::Swap<16, big_endian>::writeval(pov2 + 8, plt_entry[4]);
              elfcpp::Swap<16, big_endian>::writeval(pov2 + 10, plt_entry[5]);
              elfcpp::Swap<32, big_endian>::writeval(pov2 + 12,
                                                     gotplt_entry_addr);
              pov2 += 16;
            }
          else if (this->target_->use_32bit_micromips_instructions())
            {
              // Write microMIPS PLT entry in insn32 mode.
              const uint32_t* plt_entry = plt_entry_micromips32_o32;

              elfcpp::Swap<16, big_endian>::writeval(pov2, plt_entry[0]);
              elfcpp::Swap<16, big_endian>::writeval(pov2 + 2,
                                                     gotplt_entry_addr_hi);
              elfcpp::Swap<16, big_endian>::writeval(pov2 + 4, plt_entry[2]);
              elfcpp::Swap<16, big_endian>::writeval(pov2 + 6,
                                                     gotplt_entry_addr_lo);
              elfcpp::Swap<16, big_endian>::writeval(pov2 + 8, plt_entry[4]);
              elfcpp::Swap<16, big_endian>::writeval(pov2 + 10, plt_entry[5]);
              elfcpp::Swap<16, big_endian>::writeval(pov2 + 12, plt_entry[6]);
              elfcpp::Swap<16, big_endian>::writeval(pov2 + 14,
                                                     gotplt_entry_addr_lo);
              pov2 += 16;
            }
          else
            {
              // Write microMIPS PLT entry.
              const uint32_t* plt_entry = plt_entry_micromips_o32;

              gold_assert(gotplt_entry_addr % 4 == 0);

              Mips_address loc_address = plt_address + pov2 - oview;
              int gotpc_offset = gotplt_entry_addr - ((loc_address | 3) ^ 3);

              // ADDIUPC has a span of +/-16MB, check we're in range.
              if (gotpc_offset + 0x1000000 >= 0x2000000)
                {
                  gold_error(_(".got.plt offset of %ld from .plt beyond the "
                             "range of ADDIUPC"), (long)gotpc_offset);
                  return;
                }

              elfcpp::Swap<16, big_endian>::writeval(pov2,
                          plt_entry[0] | ((gotpc_offset >> 18) & 0x7f));
              elfcpp::Swap<16, big_endian>::writeval(
                  pov2 + 2, (gotpc_offset >> 2) & 0xffff);
              elfcpp::Swap<16, big_endian>::writeval(pov2 + 4, plt_entry[2]);
              elfcpp::Swap<16, big_endian>::writeval(pov2 + 6, plt_entry[3]);
              elfcpp::Swap<16, big_endian>::writeval(pov2 + 8, plt_entry[4]);
              elfcpp::Swap<16, big_endian>::writeval(pov2 + 10, plt_entry[5]);
              pov2 += 12;
            }
        }
    }

  // Check the number of bytes written for standard entries.
  gold_assert(static_cast<section_size_type>(
      pov - oview - this->plt_header_size_) == this->plt_mips_offset_);
  // Check the number of bytes written for compressed entries.
  gold_assert((static_cast<section_size_type>(pov2 - pov)
               == this->plt_comp_offset_));
  // Check the total number of bytes written.
  gold_assert(static_cast<section_size_type>(pov2 - oview) == oview_size);

  gold_assert(static_cast<section_size_type>(gotplt_pov - gotplt_view)
              == gotplt_size);

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

// Mips_output_data_mips_stubs methods.

// The format of the lazy binding stub when dynamic symbol count is less than
// 64K, dynamic symbol index is less than 32K, and ABI is not N64.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_mips_stubs<size, big_endian>::lazy_stub_normal_1[4] =
{
  0x8f998010,         // lw t9,0x8010(gp)
  0x03e07825,         // or t7,ra,zero
  0x0320f809,         // jalr t9,ra
  0x24180000          // addiu t8,zero,DYN_INDEX sign extended
};

// The format of the lazy binding stub when dynamic symbol count is less than
// 64K, dynamic symbol index is less than 32K, and ABI is N64.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_mips_stubs<size, big_endian>::lazy_stub_normal_1_n64[4] =
{
  0xdf998010,         // ld t9,0x8010(gp)
  0x03e07825,         // or t7,ra,zero
  0x0320f809,         // jalr t9,ra
  0x64180000          // daddiu t8,zero,DYN_INDEX sign extended
};

// The format of the lazy binding stub when dynamic symbol count is less than
// 64K, dynamic symbol index is between 32K and 64K, and ABI is not N64.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_mips_stubs<size, big_endian>::lazy_stub_normal_2[4] =
{
  0x8f998010,         // lw t9,0x8010(gp)
  0x03e07825,         // or t7,ra,zero
  0x0320f809,         // jalr t9,ra
  0x34180000          // ori t8,zero,DYN_INDEX unsigned
};

// The format of the lazy binding stub when dynamic symbol count is less than
// 64K, dynamic symbol index is between 32K and 64K, and ABI is N64.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_mips_stubs<size, big_endian>::lazy_stub_normal_2_n64[4] =
{
  0xdf998010,         // ld t9,0x8010(gp)
  0x03e07825,         // or t7,ra,zero
  0x0320f809,         // jalr t9,ra
  0x34180000          // ori t8,zero,DYN_INDEX unsigned
};

// The format of the lazy binding stub when dynamic symbol count is greater than
// 64K, and ABI is not N64.
template<int size, bool big_endian>
const uint32_t Mips_output_data_mips_stubs<size, big_endian>::lazy_stub_big[5] =
{
  0x8f998010,         // lw t9,0x8010(gp)
  0x03e07825,         // or t7,ra,zero
  0x3c180000,         // lui t8,DYN_INDEX
  0x0320f809,         // jalr t9,ra
  0x37180000          // ori t8,t8,DYN_INDEX
};

// The format of the lazy binding stub when dynamic symbol count is greater than
// 64K, and ABI is N64.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_mips_stubs<size, big_endian>::lazy_stub_big_n64[5] =
{
  0xdf998010,         // ld t9,0x8010(gp)
  0x03e07825,         // or t7,ra,zero
  0x3c180000,         // lui t8,DYN_INDEX
  0x0320f809,         // jalr t9,ra
  0x37180000          // ori t8,t8,DYN_INDEX
};

// microMIPS stubs.

// The format of the microMIPS lazy binding stub when dynamic symbol count is
// less than 64K, dynamic symbol index is less than 32K, and ABI is not N64.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_mips_stubs<size, big_endian>::lazy_stub_micromips_normal_1[] =
{
  0xff3c, 0x8010,     // lw t9,0x8010(gp)
  0x0dff,             // move t7,ra
  0x45d9,             // jalr t9
  0x3300, 0x0000      // addiu t8,zero,DYN_INDEX sign extended
};

// The format of the microMIPS lazy binding stub when dynamic symbol count is
// less than 64K, dynamic symbol index is less than 32K, and ABI is N64.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_mips_stubs<size, big_endian>::
lazy_stub_micromips_normal_1_n64[] =
{
  0xdf3c, 0x8010,     // ld t9,0x8010(gp)
  0x0dff,             // move t7,ra
  0x45d9,             // jalr t9
  0x5f00, 0x0000      // daddiu t8,zero,DYN_INDEX sign extended
};

// The format of the microMIPS lazy binding stub when dynamic symbol
// count is less than 64K, dynamic symbol index is between 32K and 64K,
// and ABI is not N64.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_mips_stubs<size, big_endian>::lazy_stub_micromips_normal_2[] =
{
  0xff3c, 0x8010,     // lw t9,0x8010(gp)
  0x0dff,             // move t7,ra
  0x45d9,             // jalr t9
  0x5300, 0x0000      // ori t8,zero,DYN_INDEX unsigned
};

// The format of the microMIPS lazy binding stub when dynamic symbol
// count is less than 64K, dynamic symbol index is between 32K and 64K,
// and ABI is N64.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_mips_stubs<size, big_endian>::
lazy_stub_micromips_normal_2_n64[] =
{
  0xdf3c, 0x8010,     // ld t9,0x8010(gp)
  0x0dff,             // move t7,ra
  0x45d9,             // jalr t9
  0x5300, 0x0000      // ori t8,zero,DYN_INDEX unsigned
};

// The format of the microMIPS lazy binding stub when dynamic symbol count is
// greater than 64K, and ABI is not N64.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_mips_stubs<size, big_endian>::lazy_stub_micromips_big[] =
{
  0xff3c, 0x8010,     // lw t9,0x8010(gp)
  0x0dff,             // move t7,ra
  0x41b8, 0x0000,     // lui t8,DYN_INDEX
  0x45d9,             // jalr t9
  0x5318, 0x0000      // ori t8,t8,DYN_INDEX
};

// The format of the microMIPS lazy binding stub when dynamic symbol count is
// greater than 64K, and ABI is N64.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_mips_stubs<size, big_endian>::lazy_stub_micromips_big_n64[] =
{
  0xdf3c, 0x8010,     // ld t9,0x8010(gp)
  0x0dff,             // move t7,ra
  0x41b8, 0x0000,     // lui t8,DYN_INDEX
  0x45d9,             // jalr t9
  0x5318, 0x0000      // ori t8,t8,DYN_INDEX
};

// 32-bit microMIPS stubs.

// The format of the microMIPS lazy binding stub when dynamic symbol count is
// less than 64K, dynamic symbol index is less than 32K, ABI is not N64, and we
// can use only 32-bit instructions.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_mips_stubs<size, big_endian>::
lazy_stub_micromips32_normal_1[] =
{
  0xff3c, 0x8010,     // lw t9,0x8010(gp)
  0x001f, 0x7a90,     // or t7,ra,zero
  0x03f9, 0x0f3c,     // jalr ra,t9
  0x3300, 0x0000      // addiu t8,zero,DYN_INDEX sign extended
};

// The format of the microMIPS lazy binding stub when dynamic symbol count is
// less than 64K, dynamic symbol index is less than 32K, ABI is N64, and we can
// use only 32-bit instructions.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_mips_stubs<size, big_endian>::
lazy_stub_micromips32_normal_1_n64[] =
{
  0xdf3c, 0x8010,     // ld t9,0x8010(gp)
  0x001f, 0x7a90,     // or t7,ra,zero
  0x03f9, 0x0f3c,     // jalr ra,t9
  0x5f00, 0x0000      // daddiu t8,zero,DYN_INDEX sign extended
};

// The format of the microMIPS lazy binding stub when dynamic symbol
// count is less than 64K, dynamic symbol index is between 32K and 64K,
// ABI is not N64, and we can use only 32-bit instructions.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_mips_stubs<size, big_endian>::
lazy_stub_micromips32_normal_2[] =
{
  0xff3c, 0x8010,     // lw t9,0x8010(gp)
  0x001f, 0x7a90,     // or t7,ra,zero
  0x03f9, 0x0f3c,     // jalr ra,t9
  0x5300, 0x0000      // ori t8,zero,DYN_INDEX unsigned
};

// The format of the microMIPS lazy binding stub when dynamic symbol
// count is less than 64K, dynamic symbol index is between 32K and 64K,
// ABI is N64, and we can use only 32-bit instructions.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_mips_stubs<size, big_endian>::
lazy_stub_micromips32_normal_2_n64[] =
{
  0xdf3c, 0x8010,     // ld t9,0x8010(gp)
  0x001f, 0x7a90,     // or t7,ra,zero
  0x03f9, 0x0f3c,     // jalr ra,t9
  0x5300, 0x0000      // ori t8,zero,DYN_INDEX unsigned
};

// The format of the microMIPS lazy binding stub when dynamic symbol count is
// greater than 64K, ABI is not N64, and we can use only 32-bit instructions.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_mips_stubs<size, big_endian>::lazy_stub_micromips32_big[] =
{
  0xff3c, 0x8010,     // lw t9,0x8010(gp)
  0x001f, 0x7a90,     // or t7,ra,zero
  0x41b8, 0x0000,     // lui t8,DYN_INDEX
  0x03f9, 0x0f3c,     // jalr ra,t9
  0x5318, 0x0000      // ori t8,t8,DYN_INDEX
};

// The format of the microMIPS lazy binding stub when dynamic symbol count is
// greater than 64K, ABI is N64, and we can use only 32-bit instructions.
template<int size, bool big_endian>
const uint32_t
Mips_output_data_mips_stubs<size, big_endian>::lazy_stub_micromips32_big_n64[] =
{
  0xdf3c, 0x8010,     // ld t9,0x8010(gp)
  0x001f, 0x7a90,     // or t7,ra,zero
  0x41b8, 0x0000,     // lui t8,DYN_INDEX
  0x03f9, 0x0f3c,     // jalr ra,t9
  0x5318, 0x0000      // ori t8,t8,DYN_INDEX
};

// Create entry for a symbol.

template<int size, bool big_endian>
void
Mips_output_data_mips_stubs<size, big_endian>::make_entry(
    Mips_symbol<size>* gsym)
{
  if (!gsym->has_lazy_stub() && !gsym->has_plt_offset())
    {
      this->symbols_.insert(gsym);
      gsym->set_has_lazy_stub(true);
    }
}

// Remove entry for a symbol.

template<int size, bool big_endian>
void
Mips_output_data_mips_stubs<size, big_endian>::remove_entry(
    Mips_symbol<size>* gsym)
{
  if (gsym->has_lazy_stub())
    {
      this->symbols_.erase(gsym);
      gsym->set_has_lazy_stub(false);
    }
}

// Set stub offsets for symbols.  This method expects that the number of
// entries in dynamic symbol table is set.

template<int size, bool big_endian>
void
Mips_output_data_mips_stubs<size, big_endian>::set_lazy_stub_offsets()
{
  gold_assert(this->dynsym_count_ != -1U);

  if (this->stub_offsets_are_set_)
    return;

  unsigned int stub_size = this->stub_size();
  unsigned int offset = 0;
  for (typename Mips_stubs_entry_set::const_iterator
       p = this->symbols_.begin();
       p != this->symbols_.end();
       ++p, offset += stub_size)
    {
      Mips_symbol<size>* mips_sym = *p;
      mips_sym->set_lazy_stub_offset(offset);
    }
  this->stub_offsets_are_set_ = true;
}

template<int size, bool big_endian>
void
Mips_output_data_mips_stubs<size, big_endian>::set_needs_dynsym_value()
{
  for (typename Mips_stubs_entry_set::const_iterator
       p = this->symbols_.begin(); p != this->symbols_.end(); ++p)
    {
      Mips_symbol<size>* sym = *p;
      if (sym->is_from_dynobj())
        sym->set_needs_dynsym_value();
    }
}

// Write out the .MIPS.stubs.  This uses the hand-coded instructions and
// adjusts them as needed.

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

  bool big_stub = this->dynsym_count_ > 0x10000;

  unsigned char* pov = oview;
  for (typename Mips_stubs_entry_set::const_iterator
       p = this->symbols_.begin(); p != this->symbols_.end(); ++p)
    {
      Mips_symbol<size>* sym = *p;
      const uint32_t* lazy_stub;
      bool n64 = this->target_->is_output_n64();

      if (!this->target_->is_output_micromips())
        {
          // Write standard (non-microMIPS) stub.
          if (!big_stub)
            {
              if (sym->dynsym_index() & ~0x7fff)
                // Dynsym index is between 32K and 64K.
                lazy_stub = n64 ? lazy_stub_normal_2_n64 : lazy_stub_normal_2;
              else
                // Dynsym index is less than 32K.
                lazy_stub = n64 ? lazy_stub_normal_1_n64 : lazy_stub_normal_1;
            }
          else
            lazy_stub = n64 ? lazy_stub_big_n64 : lazy_stub_big;

          unsigned int i = 0;
          elfcpp::Swap<32, big_endian>::writeval(pov, lazy_stub[i]);
          elfcpp::Swap<32, big_endian>::writeval(pov + 4, lazy_stub[i + 1]);
          pov += 8;

          i += 2;
          if (big_stub)
            {
              // LUI instruction of the big stub.  Paste high 16 bits of the
              // dynsym index.
              elfcpp::Swap<32, big_endian>::writeval(pov,
                  lazy_stub[i] | ((sym->dynsym_index() >> 16) & 0x7fff));
              pov += 4;
              i += 1;
            }
          elfcpp::Swap<32, big_endian>::writeval(pov, lazy_stub[i]);
          // Last stub instruction.  Paste low 16 bits of the dynsym index.
          elfcpp::Swap<32, big_endian>::writeval(pov + 4,
              lazy_stub[i + 1] | (sym->dynsym_index() & 0xffff));
          pov += 8;
        }
      else if (this->target_->use_32bit_micromips_instructions())
        {
          // Write microMIPS stub in insn32 mode.
          if (!big_stub)
            {
              if (sym->dynsym_index() & ~0x7fff)
                // Dynsym index is between 32K and 64K.
                lazy_stub = n64 ? lazy_stub_micromips32_normal_2_n64
                                : lazy_stub_micromips32_normal_2;
              else
                // Dynsym index is less than 32K.
                lazy_stub = n64 ? lazy_stub_micromips32_normal_1_n64
                                : lazy_stub_micromips32_normal_1;
            }
          else
            lazy_stub = n64 ? lazy_stub_micromips32_big_n64
                            : lazy_stub_micromips32_big;

          unsigned int i = 0;
          // First stub instruction.  We emit 32-bit microMIPS instructions by
          // emitting two 16-bit parts because on microMIPS the 16-bit part of
          // the instruction where the opcode is must always come first, for
          // both little and big endian.
          elfcpp::Swap<16, big_endian>::writeval(pov, lazy_stub[i]);
          elfcpp::Swap<16, big_endian>::writeval(pov + 2, lazy_stub[i + 1]);
          // Second stub instruction.
          elfcpp::Swap<16, big_endian>::writeval(pov + 4, lazy_stub[i + 2]);
          elfcpp::Swap<16, big_endian>::writeval(pov + 6, lazy_stub[i + 3]);
          pov += 8;
          i += 4;
          if (big_stub)
            {
              // LUI instruction of the big stub.  Paste high 16 bits of the
              // dynsym index.
              elfcpp::Swap<16, big_endian>::writeval(pov, lazy_stub[i]);
              elfcpp::Swap<16, big_endian>::writeval(pov + 2,
                  (sym->dynsym_index() >> 16) & 0x7fff);
              pov += 4;
              i += 2;
            }
          elfcpp::Swap<16, big_endian>::writeval(pov, lazy_stub[i]);
          elfcpp::Swap<16, big_endian>::writeval(pov + 2, lazy_stub[i + 1]);
          // Last stub instruction.  Paste low 16 bits of the dynsym index.
          elfcpp::Swap<16, big_endian>::writeval(pov + 4, lazy_stub[i + 2]);
          elfcpp::Swap<16, big_endian>::writeval(pov + 6,
              sym->dynsym_index() & 0xffff);
          pov += 8;
        }
      else
        {
          // Write microMIPS stub.
          if (!big_stub)
            {
              if (sym->dynsym_index() & ~0x7fff)
                // Dynsym index is between 32K and 64K.
                lazy_stub = n64 ? lazy_stub_micromips_normal_2_n64
                                : lazy_stub_micromips_normal_2;
              else
                // Dynsym index is less than 32K.
                lazy_stub = n64 ? lazy_stub_micromips_normal_1_n64
                                : lazy_stub_micromips_normal_1;
            }
          else
            lazy_stub = n64 ? lazy_stub_micromips_big_n64
                            : lazy_stub_micromips_big;

          unsigned int i = 0;
          // First stub instruction.  We emit 32-bit microMIPS instructions by
          // emitting two 16-bit parts because on microMIPS the 16-bit part of
          // the instruction where the opcode is must always come first, for
          // both little and big endian.
          elfcpp::Swap<16, big_endian>::writeval(pov, lazy_stub[i]);
          elfcpp::Swap<16, big_endian>::writeval(pov + 2, lazy_stub[i + 1]);
          // Second stub instruction.
          elfcpp::Swap<16, big_endian>::writeval(pov + 4, lazy_stub[i + 2]);
          pov += 6;
          i += 3;
          if (big_stub)
            {
              // LUI instruction of the big stub.  Paste high 16 bits of the
              // dynsym index.
              elfcpp::Swap<16, big_endian>::writeval(pov, lazy_stub[i]);
              elfcpp::Swap<16, big_endian>::writeval(pov + 2,
                  (sym->dynsym_index() >> 16) & 0x7fff);
              pov += 4;
              i += 2;
            }
          elfcpp::Swap<16, big_endian>::writeval(pov, lazy_stub[i]);
          // Last stub instruction.  Paste low 16 bits of the dynsym index.
          elfcpp::Swap<16, big_endian>::writeval(pov + 2, lazy_stub[i + 1]);
          elfcpp::Swap<16, big_endian>::writeval(pov + 4,
              sym->dynsym_index() & 0xffff);
          pov += 6;
        }
    }

  // We always allocate 20 bytes for every stub, because final dynsym count is
  // not known in method do_finalize_sections.  There are 4 unused bytes per
  // stub if final dynsym count is less than 0x10000.
  unsigned int used = pov - oview;
  unsigned int unused = big_stub ? 0 : this->symbols_.size() * 4;
  gold_assert(static_cast<section_size_type>(used + unused) == oview_size);

  // Fill the unused space with zeroes.
  // TODO(sasa): Can we strip unused bytes during the relaxation?
  if (unused > 0)
    memset(pov, 0, unused);

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

// Mips_output_section_reginfo methods.

template<int size, bool big_endian>
void
Mips_output_section_reginfo<size, big_endian>::do_write(Output_file* of)
{
  off_t offset = this->offset();
  off_t data_size = this->data_size();

  unsigned char* view = of->get_output_view(offset, data_size);
  elfcpp::Swap<size, big_endian>::writeval(view, this->gprmask_);
  elfcpp::Swap<size, big_endian>::writeval(view + 4, this->cprmask1_);
  elfcpp::Swap<size, big_endian>::writeval(view + 8, this->cprmask2_);
  elfcpp::Swap<size, big_endian>::writeval(view + 12, this->cprmask3_);
  elfcpp::Swap<size, big_endian>::writeval(view + 16, this->cprmask4_);
  // Write the gp value.
  elfcpp::Swap<size, big_endian>::writeval(view + 20,
                                           this->target_->gp_value());

  of->write_output_view(offset, data_size, view);
}

// Mips_output_section_options methods.

template<int size, bool big_endian>
void
Mips_output_section_options<size, big_endian>::do_write(Output_file* of)
{
  off_t offset = this->offset();
  const section_size_type oview_size =
    convert_to_section_size_type(this->data_size());
  unsigned char* view = of->get_output_view(offset, oview_size);
  const unsigned char* end = view + oview_size;

  while (view + 8 <= end)
    {
      unsigned char kind = elfcpp::Swap<8, big_endian>::readval(view);
      unsigned char sz = elfcpp::Swap<8, big_endian>::readval(view + 1);
      if (sz < 8)
        {
          gold_error(_("Warning: bad `%s' option size %u smaller "
                       "than its header in output section"),
                     this->name(), sz);
          break;
        }

      // Only update ri_gp_value (GP register value) field of ODK_REGINFO entry.
      if (this->target_->is_output_n64() && kind == elfcpp::ODK_REGINFO)
        elfcpp::Swap<size, big_endian>::writeval(view + 32,
                                                 this->target_->gp_value());
      else if (kind == elfcpp::ODK_REGINFO)
        elfcpp::Swap<size, big_endian>::writeval(view + 28,
                                                 this->target_->gp_value());

      view += sz;
    }

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

// Mips_output_section_abiflags methods.

template<int size, bool big_endian>
void
Mips_output_section_abiflags<size, big_endian>::do_write(Output_file* of)
{
  off_t offset = this->offset();
  off_t data_size = this->data_size();

  unsigned char* view = of->get_output_view(offset, data_size);
  elfcpp::Swap<16, big_endian>::writeval(view, this->abiflags_.version);
  elfcpp::Swap<8, big_endian>::writeval(view + 2, this->abiflags_.isa_level);
  elfcpp::Swap<8, big_endian>::writeval(view + 3, this->abiflags_.isa_rev);
  elfcpp::Swap<8, big_endian>::writeval(view + 4, this->abiflags_.gpr_size);
  elfcpp::Swap<8, big_endian>::writeval(view + 5, this->abiflags_.cpr1_size);
  elfcpp::Swap<8, big_endian>::writeval(view + 6, this->abiflags_.cpr2_size);
  elfcpp::Swap<8, big_endian>::writeval(view + 7, this->abiflags_.fp_abi);
  elfcpp::Swap<32, big_endian>::writeval(view + 8, this->abiflags_.isa_ext);
  elfcpp::Swap<32, big_endian>::writeval(view + 12, this->abiflags_.ases);
  elfcpp::Swap<32, big_endian>::writeval(view + 16, this->abiflags_.flags1);
  elfcpp::Swap<32, big_endian>::writeval(view + 20, this->abiflags_.flags2);

  of->write_output_view(offset, data_size, view);
}

// Mips_copy_relocs methods.

// Emit any saved relocs.

template<int sh_type, int size, bool big_endian>
void
Mips_copy_relocs<sh_type, size, big_endian>::emit_mips(
    Output_data_reloc<sh_type, true, size, big_endian>* reloc_section,
    Symbol_table* symtab, Layout* layout, Target_mips<size, big_endian>* target)
{
  for (typename Copy_relocs<sh_type, size, big_endian>::
       Copy_reloc_entries::iterator p = this->entries_.begin();
       p != this->entries_.end();
       ++p)
    emit_entry(*p, reloc_section, symtab, layout, target);

  // We no longer need the saved information.
  this->entries_.clear();
}

// Emit the reloc if appropriate.

template<int sh_type, int size, bool big_endian>
void
Mips_copy_relocs<sh_type, size, big_endian>::emit_entry(
    Copy_reloc_entry& entry,
    Output_data_reloc<sh_type, true, size, big_endian>* reloc_section,
    Symbol_table* symtab, Layout* layout, Target_mips<size, big_endian>* target)
{
  // If the symbol is no longer defined in a dynamic object, then we
  // emitted a COPY relocation, and we do not want to emit this
  // dynamic relocation.
  if (!entry.sym_->is_from_dynobj())
    return;

  bool can_make_dynamic = (entry.reloc_type_ == elfcpp::R_MIPS_32
                           || entry.reloc_type_ == elfcpp::R_MIPS_REL32
                           || entry.reloc_type_ == elfcpp::R_MIPS_64);

  Mips_symbol<size>* sym = Mips_symbol<size>::as_mips_sym(entry.sym_);
  if (can_make_dynamic && !sym->has_static_relocs())
    {
      Mips_relobj<size, big_endian>* object =
        Mips_relobj<size, big_endian>::as_mips_relobj(entry.relobj_);
      target->got_section(symtab, layout)->record_global_got_symbol(
                          sym, object, entry.reloc_type_, true, false);
      if (!symbol_references_local(sym, sym->should_add_dynsym_entry(symtab)))
        target->rel_dyn_section(layout)->add_global(sym, elfcpp::R_MIPS_REL32,
            entry.output_section_, entry.relobj_, entry.shndx_, entry.address_);
      else
        target->rel_dyn_section(layout)->add_symbolless_global_addend(
            sym, elfcpp::R_MIPS_REL32, entry.output_section_, entry.relobj_,
            entry.shndx_, entry.address_);
    }
  else
    this->make_copy_reloc(symtab, layout,
                          static_cast<Sized_symbol<size>*>(entry.sym_),
                          entry.relobj_,
                          reloc_section);
}

// Target_mips methods.

// Return the value to use for a dynamic symbol which requires special
// treatment.  This is how we support equality comparisons of function
// pointers across shared library boundaries, as described in the
// processor specific ABI supplement.

template<int size, bool big_endian>
uint64_t
Target_mips<size, big_endian>::do_dynsym_value(const Symbol* gsym) const
{
  uint64_t value = 0;
  const Mips_symbol<size>* mips_sym = Mips_symbol<size>::as_mips_sym(gsym);

  if (!mips_sym->has_lazy_stub())
    {
      if (mips_sym->has_plt_offset())
        {
          // We distinguish between PLT entries and lazy-binding stubs by
          // giving the former an st_other value of STO_MIPS_PLT.  Set the
          // value to the stub address if there are any relocations in the
          // binary where pointer equality matters.
          if (mips_sym->pointer_equality_needed())
            {
              // Prefer a standard MIPS PLT entry.
              if (mips_sym->has_mips_plt_offset())
                value = this->plt_section()->mips_entry_address(mips_sym);
              else
                value = this->plt_section()->comp_entry_address(mips_sym) + 1;
            }
          else
            value = 0;
        }
    }
  else
    {
      // First, set stub offsets for symbols.  This method expects that the
      // number of entries in dynamic symbol table is set.
      this->mips_stubs_section()->set_lazy_stub_offsets();

      // The run-time linker uses the st_value field of the symbol
      // to reset the global offset table entry for this external
      // to its stub address when unlinking a shared object.
      value = this->mips_stubs_section()->stub_address(mips_sym);
    }

  if (mips_sym->has_mips16_fn_stub())
    {
      // If we have a MIPS16 function with a stub, the dynamic symbol must
      // refer to the stub, since only the stub uses the standard calling
      // conventions.
      value = mips_sym->template
              get_mips16_fn_stub<big_endian>()->output_address();
    }

  return value;
}

// Get the dynamic reloc section, creating it if necessary.  It's always
// .rel.dyn, even for MIPS64.

template<int size, bool big_endian>
typename Target_mips<size, big_endian>::Reloc_section*
Target_mips<size, 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);

      // First entry in .rel.dyn has to be null.
      // This is hack - we define dummy output data and set its address to 0,
      // and define absolute R_MIPS_NONE relocation with offset 0 against it.
      // This ensures that the entry is null.
      Output_data* od = new Output_data_zero_fill(0, 0);
      od->set_address(0);
      this->rel_dyn_->add_absolute(elfcpp::R_MIPS_NONE, od, 0);
    }
  return this->rel_dyn_;
}

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

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

      this->got_ = new Mips_output_data_got<size, big_endian>(this, symtab,
                                                              layout);
      layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
                                      (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE |
                                      elfcpp::SHF_MIPS_GPREL),
                                      this->got_, ORDER_DATA, false);

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

  return this->got_;
}

// Calculate value of _gp symbol.

template<int size, bool big_endian>
void
Target_mips<size, big_endian>::set_gp(Layout* layout, Symbol_table* symtab)
{
  gold_assert(this->gp_ == NULL);

  Sized_symbol<size>* gp =
    static_cast<Sized_symbol<size>*>(symtab->lookup("_gp"));

  // Set _gp symbol if the linker script hasn't created it.
  if (gp == NULL || gp->source() != Symbol::IS_CONSTANT)
    {
      // If there is no .got section, gp should be based on .sdata.
      Output_data* gp_section = (this->got_ != NULL
                                 ? this->got_->output_section()
                                 : layout->find_output_section(".sdata"));

      if (gp_section != NULL)
        gp = static_cast<Sized_symbol<size>*>(symtab->define_in_output_data(
                                          "_gp", NULL, Symbol_table::PREDEFINED,
                                          gp_section, MIPS_GP_OFFSET, 0,
                                          elfcpp::STT_NOTYPE,
                                          elfcpp::STB_LOCAL,
                                          elfcpp::STV_DEFAULT,
                                          0, false, false));
    }

  this->gp_ = gp;
}

// Set the dynamic symbol indexes.  INDEX is the index of the first
// global dynamic symbol.  Pointers to the symbols are stored into the
// vector SYMS.  The names are added to DYNPOOL.  This returns an
// updated dynamic symbol index.

template<int size, bool big_endian>
unsigned int
Target_mips<size, big_endian>::do_set_dynsym_indexes(
    std::vector<Symbol*>* dyn_symbols, unsigned int index,
    std::vector<Symbol*>* syms, Stringpool* dynpool,
    Versions* versions, Symbol_table* symtab) const
{
  std::vector<Symbol*> non_got_symbols;
  std::vector<Symbol*> got_symbols;

  reorder_dyn_symbols<size, big_endian>(dyn_symbols, &non_got_symbols,
                                        &got_symbols);

  for (std::vector<Symbol*>::iterator p = non_got_symbols.begin();
       p != non_got_symbols.end();
       ++p)
    {
      Symbol* sym = *p;

      // Note that SYM may already have a dynamic symbol index, since
      // some symbols appear more than once in the symbol table, with
      // and without a version.

      if (!sym->has_dynsym_index())
        {
          sym->set_dynsym_index(index);
          ++index;
          syms->push_back(sym);
          dynpool->add(sym->name(), false, NULL);

          // Record any version information.
          if (sym->version() != NULL)
            versions->record_version(symtab, dynpool, sym);

          // If the symbol is defined in a dynamic object and is
          // referenced in a regular object, then mark the dynamic
          // object as needed.  This is used to implement --as-needed.
          if (sym->is_from_dynobj() && sym->in_reg())
            sym->object()->set_is_needed();
        }
    }

  for (std::vector<Symbol*>::iterator p = got_symbols.begin();
       p != got_symbols.end();
       ++p)
    {
      Symbol* sym = *p;
      if (!sym->has_dynsym_index())
        {
          // Record any version information.
          if (sym->version() != NULL)
            versions->record_version(symtab, dynpool, sym);
        }
    }

  index = versions->finalize(symtab, index, syms);

  int got_sym_count = 0;
  for (std::vector<Symbol*>::iterator p = got_symbols.begin();
       p != got_symbols.end();
       ++p)
    {
      Symbol* sym = *p;

      if (!sym->has_dynsym_index())
        {
          ++got_sym_count;
          sym->set_dynsym_index(index);
          ++index;
          syms->push_back(sym);
          dynpool->add(sym->name(), false, NULL);

          // If the symbol is defined in a dynamic object and is
          // referenced in a regular object, then mark the dynamic
          // object as needed.  This is used to implement --as-needed.
          if (sym->is_from_dynobj() && sym->in_reg())
            sym->object()->set_is_needed();
        }
    }

  // Set index of the first symbol that has .got entry.
  this->got_->set_first_global_got_dynsym_index(
    got_sym_count > 0 ? index - got_sym_count : -1U);

  if (this->mips_stubs_ != NULL)
    this->mips_stubs_->set_dynsym_count(index);

  return index;
}

// Create a PLT entry for a global symbol referenced by r_type relocation.

template<int size, bool big_endian>
void
Target_mips<size, big_endian>::make_plt_entry(Symbol_table* symtab,
                                              Layout* layout,
                                              Mips_symbol<size>* gsym,
                                              unsigned int r_type)
{
  if (gsym->has_lazy_stub() || gsym->has_plt_offset())
    return;

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

      this->got_plt_ = new Output_data_space(4, "** GOT PLT");
      layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
                                      (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
                                      this->got_plt_, ORDER_DATA, false);

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

      this->plt_ = new Mips_output_data_plt<size, big_endian>(layout,
                                                              this->got_plt_,
                                                              this);
      layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
                                      (elfcpp::SHF_ALLOC
                                       | elfcpp::SHF_EXECINSTR),
                                      this->plt_, ORDER_PLT, false);

      // Make the sh_info field of .rel.plt point to .plt.
      Output_section* rel_plt_os = this->plt_->rel_plt()->output_section();
      rel_plt_os->set_info_section(this->plt_->output_section());
    }

  this->plt_->add_entry(gsym, r_type);
}


// Get the .MIPS.stubs section, creating it if necessary.

template<int size, bool big_endian>
Mips_output_data_mips_stubs<size, big_endian>*
Target_mips<size, big_endian>::mips_stubs_section(Layout* layout)
{
  if (this->mips_stubs_ == NULL)
    {
      this->mips_stubs_ =
        new Mips_output_data_mips_stubs<size, big_endian>(this);
      layout->add_output_section_data(".MIPS.stubs", elfcpp::SHT_PROGBITS,
                                      (elfcpp::SHF_ALLOC
                                       | elfcpp::SHF_EXECINSTR),
                                      this->mips_stubs_, ORDER_PLT, false);
    }
  return this->mips_stubs_;
}

// Get the LA25 stub section, creating it if necessary.

template<int size, bool big_endian>
Mips_output_data_la25_stub<size, big_endian>*
Target_mips<size, big_endian>::la25_stub_section(Layout* layout)
{
  if (this->la25_stub_ == NULL)
    {
      this->la25_stub_ = new Mips_output_data_la25_stub<size, big_endian>();
      layout->add_output_section_data(".text", elfcpp::SHT_PROGBITS,
                                      (elfcpp::SHF_ALLOC
                                       | elfcpp::SHF_EXECINSTR),
                                      this->la25_stub_, ORDER_TEXT, false);
    }
  return this->la25_stub_;
}

// Process the relocations to determine unreferenced sections for
// garbage collection.

template<int size, bool big_endian>
void
Target_mips<size, big_endian>::gc_process_relocs(
                        Symbol_table* symtab,
                        Layout* layout,
                        Sized_relobj_file<size, big_endian>* object,
                        unsigned int data_shndx,
                        unsigned int sh_type,
                        const unsigned char* prelocs,
                        size_t reloc_count,
                        Output_section* output_section,
                        bool needs_special_offset_handling,
                        size_t local_symbol_count,
                        const unsigned char* plocal_symbols)
{
  typedef Target_mips<size, big_endian> Mips;

  if (sh_type == elfcpp::SHT_REL)
    {
      typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>
          Classify_reloc;

      gold::gc_process_relocs<size, big_endian, Mips, Scan, Classify_reloc>(
        symtab,
        layout,
        this,
        object,
        data_shndx,
        prelocs,
        reloc_count,
        output_section,
        needs_special_offset_handling,
        local_symbol_count,
        plocal_symbols);
    }
  else if (sh_type == elfcpp::SHT_RELA)
    {
      typedef Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
          Classify_reloc;

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

// Scan relocations for a section.

template<int size, bool big_endian>
void
Target_mips<size, big_endian>::scan_relocs(
                        Symbol_table* symtab,
                        Layout* layout,
                        Sized_relobj_file<size, big_endian>* object,
                        unsigned int data_shndx,
                        unsigned int sh_type,
                        const unsigned char* prelocs,
                        size_t reloc_count,
                        Output_section* output_section,
                        bool needs_special_offset_handling,
                        size_t local_symbol_count,
                        const unsigned char* plocal_symbols)
{
  typedef Target_mips<size, big_endian> Mips;

  if (sh_type == elfcpp::SHT_REL)
    {
      typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>
	  Classify_reloc;

      gold::scan_relocs<size, big_endian, Mips, Scan, Classify_reloc>(
	symtab,
	layout,
	this,
	object,
	data_shndx,
	prelocs,
	reloc_count,
	output_section,
	needs_special_offset_handling,
	local_symbol_count,
	plocal_symbols);
    }
  else if (sh_type == elfcpp::SHT_RELA)
    {
      typedef Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
	  Classify_reloc;

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

template<int size, bool big_endian>
bool
Target_mips<size, big_endian>::mips_32bit_flags(elfcpp::Elf_Word flags)
{
  return ((flags & elfcpp::EF_MIPS_32BITMODE) != 0
          || (flags & elfcpp::EF_MIPS_ABI) == elfcpp::E_MIPS_ABI_O32
          || (flags & elfcpp::EF_MIPS_ABI) == elfcpp::E_MIPS_ABI_EABI32
          || (flags & elfcpp::EF_MIPS_ARCH) == elfcpp::E_MIPS_ARCH_1
          || (flags & elfcpp::EF_MIPS_ARCH) == elfcpp::E_MIPS_ARCH_2
          || (flags & elfcpp::EF_MIPS_ARCH) == elfcpp::E_MIPS_ARCH_32
          || (flags & elfcpp::EF_MIPS_ARCH) == elfcpp::E_MIPS_ARCH_32R2
          || (flags & elfcpp::EF_MIPS_ARCH) == elfcpp::E_MIPS_ARCH_32R6);
}

// Return the MACH for a MIPS e_flags value.
template<int size, bool big_endian>
unsigned int
Target_mips<size, big_endian>::elf_mips_mach(elfcpp::Elf_Word flags)
{
  switch (flags & elfcpp::EF_MIPS_MACH)
    {
    case elfcpp::E_MIPS_MACH_3900:
      return mach_mips3900;

    case elfcpp::E_MIPS_MACH_4010:
      return mach_mips4010;

    case elfcpp::E_MIPS_MACH_4100:
      return mach_mips4100;

    case elfcpp::E_MIPS_MACH_4111:
      return mach_mips4111;

    case elfcpp::E_MIPS_MACH_4120:
      return mach_mips4120;

    case elfcpp::E_MIPS_MACH_4650:
      return mach_mips4650;

    case elfcpp::E_MIPS_MACH_5400:
      return mach_mips5400;

    case elfcpp::E_MIPS_MACH_5500:
      return mach_mips5500;

    case elfcpp::E_MIPS_MACH_5900:
      return mach_mips5900;

    case elfcpp::E_MIPS_MACH_9000:
      return mach_mips9000;

    case elfcpp::E_MIPS_MACH_SB1:
      return mach_mips_sb1;

    case elfcpp::E_MIPS_MACH_LS2E:
      return mach_mips_loongson_2e;

    case elfcpp::E_MIPS_MACH_LS2F:
      return mach_mips_loongson_2f;

    case elfcpp::E_MIPS_MACH_LS3A:
      return mach_mips_loongson_3a;

    case elfcpp::E_MIPS_MACH_OCTEON3:
      return mach_mips_octeon3;

    case elfcpp::E_MIPS_MACH_OCTEON2:
      return mach_mips_octeon2;

    case elfcpp::E_MIPS_MACH_OCTEON:
      return mach_mips_octeon;

    case elfcpp::E_MIPS_MACH_XLR:
      return mach_mips_xlr;

    default:
      switch (flags & elfcpp::EF_MIPS_ARCH)
        {
        default:
        case elfcpp::E_MIPS_ARCH_1:
          return mach_mips3000;

        case elfcpp::E_MIPS_ARCH_2:
          return mach_mips6000;

        case elfcpp::E_MIPS_ARCH_3:
          return mach_mips4000;

        case elfcpp::E_MIPS_ARCH_4:
          return mach_mips8000;

        case elfcpp::E_MIPS_ARCH_5:
          return mach_mips5;

        case elfcpp::E_MIPS_ARCH_32:
          return mach_mipsisa32;

        case elfcpp::E_MIPS_ARCH_64:
          return mach_mipsisa64;

        case elfcpp::E_MIPS_ARCH_32R2:
          return mach_mipsisa32r2;

        case elfcpp::E_MIPS_ARCH_32R6:
          return mach_mipsisa32r6;

        case elfcpp::E_MIPS_ARCH_64R2:
          return mach_mipsisa64r2;

        case elfcpp::E_MIPS_ARCH_64R6:
          return mach_mipsisa64r6;
        }
    }

  return 0;
}

// Return the MACH for each .MIPS.abiflags ISA Extension.

template<int size, bool big_endian>
unsigned int
Target_mips<size, big_endian>::mips_isa_ext_mach(unsigned int isa_ext)
{
  switch (isa_ext)
    {
    case elfcpp::AFL_EXT_3900:
      return mach_mips3900;

    case elfcpp::AFL_EXT_4010:
      return mach_mips4010;

    case elfcpp::AFL_EXT_4100:
      return mach_mips4100;

    case elfcpp::AFL_EXT_4111:
      return mach_mips4111;

    case elfcpp::AFL_EXT_4120:
      return mach_mips4120;

    case elfcpp::AFL_EXT_4650:
      return mach_mips4650;

    case elfcpp::AFL_EXT_5400:
      return mach_mips5400;

    case elfcpp::AFL_EXT_5500:
      return mach_mips5500;

    case elfcpp::AFL_EXT_5900:
      return mach_mips5900;

    case elfcpp::AFL_EXT_10000:
      return mach_mips10000;

    case elfcpp::AFL_EXT_LOONGSON_2E:
      return mach_mips_loongson_2e;

    case elfcpp::AFL_EXT_LOONGSON_2F:
      return mach_mips_loongson_2f;

    case elfcpp::AFL_EXT_LOONGSON_3A:
      return mach_mips_loongson_3a;

    case elfcpp::AFL_EXT_SB1:
      return mach_mips_sb1;

    case elfcpp::AFL_EXT_OCTEON:
      return mach_mips_octeon;

    case elfcpp::AFL_EXT_OCTEONP:
      return mach_mips_octeonp;

    case elfcpp::AFL_EXT_OCTEON2:
      return mach_mips_octeon2;

    case elfcpp::AFL_EXT_XLR:
      return mach_mips_xlr;

    default:
      return mach_mips3000;
    }
}

// Return the .MIPS.abiflags value representing each ISA Extension.

template<int size, bool big_endian>
unsigned int
Target_mips<size, big_endian>::mips_isa_ext(unsigned int mips_mach)
{
  switch (mips_mach)
    {
    case mach_mips3900:
      return elfcpp::AFL_EXT_3900;

    case mach_mips4010:
      return elfcpp::AFL_EXT_4010;

    case mach_mips4100:
      return elfcpp::AFL_EXT_4100;

    case mach_mips4111:
      return elfcpp::AFL_EXT_4111;

    case mach_mips4120:
      return elfcpp::AFL_EXT_4120;

    case mach_mips4650:
      return elfcpp::AFL_EXT_4650;

    case mach_mips5400:
      return elfcpp::AFL_EXT_5400;

    case mach_mips5500:
      return elfcpp::AFL_EXT_5500;

    case mach_mips5900:
      return elfcpp::AFL_EXT_5900;

    case mach_mips10000:
      return elfcpp::AFL_EXT_10000;

    case mach_mips_loongson_2e:
      return elfcpp::AFL_EXT_LOONGSON_2E;

    case mach_mips_loongson_2f:
      return elfcpp::AFL_EXT_LOONGSON_2F;

    case mach_mips_loongson_3a:
      return elfcpp::AFL_EXT_LOONGSON_3A;

    case mach_mips_sb1:
      return elfcpp::AFL_EXT_SB1;

    case mach_mips_octeon:
      return elfcpp::AFL_EXT_OCTEON;

    case mach_mips_octeonp:
      return elfcpp::AFL_EXT_OCTEONP;

    case mach_mips_octeon3:
      return elfcpp::AFL_EXT_OCTEON3;

    case mach_mips_octeon2:
      return elfcpp::AFL_EXT_OCTEON2;

    case mach_mips_xlr:
      return elfcpp::AFL_EXT_XLR;

    default:
      return 0;
    }
}

// Update the isa_level, isa_rev, isa_ext fields of abiflags.

template<int size, bool big_endian>
void
Target_mips<size, big_endian>::update_abiflags_isa(const std::string& name,
    elfcpp::Elf_Word e_flags, Mips_abiflags<big_endian>* abiflags)
{
  int new_isa = 0;
  switch (e_flags & elfcpp::EF_MIPS_ARCH)
    {
    case elfcpp::E_MIPS_ARCH_1:
      new_isa = this->level_rev(1, 0);
      break;
    case elfcpp::E_MIPS_ARCH_2:
      new_isa = this->level_rev(2, 0);
      break;
    case elfcpp::E_MIPS_ARCH_3:
      new_isa = this->level_rev(3, 0);
      break;
    case elfcpp::E_MIPS_ARCH_4:
      new_isa = this->level_rev(4, 0);
      break;
    case elfcpp::E_MIPS_ARCH_5:
      new_isa = this->level_rev(5, 0);
      break;
    case elfcpp::E_MIPS_ARCH_32:
      new_isa = this->level_rev(32, 1);
      break;
    case elfcpp::E_MIPS_ARCH_32R2:
      new_isa = this->level_rev(32, 2);
      break;
    case elfcpp::E_MIPS_ARCH_32R6:
      new_isa = this->level_rev(32, 6);
      break;
    case elfcpp::E_MIPS_ARCH_64:
      new_isa = this->level_rev(64, 1);
      break;
    case elfcpp::E_MIPS_ARCH_64R2:
      new_isa = this->level_rev(64, 2);
      break;
    case elfcpp::E_MIPS_ARCH_64R6:
      new_isa = this->level_rev(64, 6);
      break;
    default:
      gold_error(_("%s: Unknown architecture %s"), name.c_str(),
                 this->elf_mips_mach_name(e_flags));
    }

  if (new_isa > this->level_rev(abiflags->isa_level, abiflags->isa_rev))
    {
      // Decode a single value into level and revision.
      abiflags->isa_level = new_isa >> 3;
      abiflags->isa_rev = new_isa & 0x7;
    }

  // Update the isa_ext if needed.
  if (this->mips_mach_extends(this->mips_isa_ext_mach(abiflags->isa_ext),
      this->elf_mips_mach(e_flags)))
    abiflags->isa_ext = this->mips_isa_ext(this->elf_mips_mach(e_flags));
}

// Infer the content of the ABI flags based on the elf header.

template<int size, bool big_endian>
void
Target_mips<size, big_endian>::infer_abiflags(
    Mips_relobj<size, big_endian>* relobj, Mips_abiflags<big_endian>* abiflags)
{
  const Attributes_section_data* pasd = relobj->attributes_section_data();
  int attr_fp_abi = elfcpp::Val_GNU_MIPS_ABI_FP_ANY;
  elfcpp::Elf_Word e_flags = relobj->processor_specific_flags();

  this->update_abiflags_isa(relobj->name(), e_flags, abiflags);
  if (pasd != NULL)
    {
      // Read fp_abi from the .gnu.attribute section.
      const Object_attribute* attr =
        pasd->known_attributes(Object_attribute::OBJ_ATTR_GNU);
      attr_fp_abi = attr[elfcpp::Tag_GNU_MIPS_ABI_FP].int_value();
    }

  abiflags->fp_abi = attr_fp_abi;
  abiflags->cpr1_size = elfcpp::AFL_REG_NONE;
  abiflags->cpr2_size = elfcpp::AFL_REG_NONE;
  abiflags->gpr_size = this->mips_32bit_flags(e_flags) ? elfcpp::AFL_REG_32
                                                       : elfcpp::AFL_REG_64;

  if (abiflags->fp_abi == elfcpp::Val_GNU_MIPS_ABI_FP_SINGLE
      || abiflags->fp_abi == elfcpp::Val_GNU_MIPS_ABI_FP_XX
      || (abiflags->fp_abi == elfcpp::Val_GNU_MIPS_ABI_FP_DOUBLE
      && abiflags->gpr_size == elfcpp::AFL_REG_32))
    abiflags->cpr1_size = elfcpp::AFL_REG_32;
  else if (abiflags->fp_abi == elfcpp::Val_GNU_MIPS_ABI_FP_DOUBLE
           || abiflags->fp_abi == elfcpp::Val_GNU_MIPS_ABI_FP_64
           || abiflags->fp_abi == elfcpp::Val_GNU_MIPS_ABI_FP_64A)
    abiflags->cpr1_size = elfcpp::AFL_REG_64;

  if (e_flags & elfcpp::EF_MIPS_ARCH_ASE_MDMX)
    abiflags->ases |= elfcpp::AFL_ASE_MDMX;
  if (e_flags & elfcpp::EF_MIPS_ARCH_ASE_M16)
    abiflags->ases |= elfcpp::AFL_ASE_MIPS16;
  if (e_flags & elfcpp::EF_MIPS_ARCH_ASE_MICROMIPS)
    abiflags->ases |= elfcpp::AFL_ASE_MICROMIPS;

  if (abiflags->fp_abi != elfcpp::Val_GNU_MIPS_ABI_FP_ANY
      && abiflags->fp_abi != elfcpp::Val_GNU_MIPS_ABI_FP_SOFT
      && abiflags->fp_abi != elfcpp::Val_GNU_MIPS_ABI_FP_64A
      && abiflags->isa_level >= 32
      && abiflags->isa_ext != elfcpp::AFL_EXT_LOONGSON_3A)
    abiflags->flags1 |= elfcpp::AFL_FLAGS1_ODDSPREG;
}

// Create abiflags from elf header or from .MIPS.abiflags section.

template<int size, bool big_endian>
void
Target_mips<size, big_endian>::create_abiflags(
    Mips_relobj<size, big_endian>* relobj,
    Mips_abiflags<big_endian>* abiflags)
{
  Mips_abiflags<big_endian>* sec_abiflags = relobj->abiflags();
  Mips_abiflags<big_endian> header_abiflags;

  this->infer_abiflags(relobj, &header_abiflags);

  if (sec_abiflags == NULL)
    {
      // If there is no input .MIPS.abiflags section, use abiflags created
      // from elf header.
      *abiflags = header_abiflags;
      return;
    }

  this->has_abiflags_section_ = true;

  // It is not possible to infer the correct ISA revision for R3 or R5
  // so drop down to R2 for the checks.
  unsigned char isa_rev = sec_abiflags->isa_rev;
  if (isa_rev == 3 || isa_rev == 5)
    isa_rev = 2;

  // Check compatibility between abiflags created from elf header
  // and abiflags from .MIPS.abiflags section in this object file.
  if (this->level_rev(sec_abiflags->isa_level, isa_rev)
      < this->level_rev(header_abiflags.isa_level, header_abiflags.isa_rev))
    gold_warning(_("%s: Inconsistent ISA between e_flags and .MIPS.abiflags"),
                 relobj->name().c_str());
  if (header_abiflags.fp_abi != elfcpp::Val_GNU_MIPS_ABI_FP_ANY
      && sec_abiflags->fp_abi != header_abiflags.fp_abi)
    gold_warning(_("%s: Inconsistent FP ABI between .gnu.attributes and "
                   ".MIPS.abiflags"), relobj->name().c_str());
  if ((sec_abiflags->ases & header_abiflags.ases) != header_abiflags.ases)
    gold_warning(_("%s: Inconsistent ASEs between e_flags and .MIPS.abiflags"),
                 relobj->name().c_str());
  // The isa_ext is allowed to be an extension of what can be inferred
  // from e_flags.
  if (!this->mips_mach_extends(this->mips_isa_ext_mach(header_abiflags.isa_ext),
                               this->mips_isa_ext_mach(sec_abiflags->isa_ext)))
    gold_warning(_("%s: Inconsistent ISA extensions between e_flags and "
                   ".MIPS.abiflags"), relobj->name().c_str());
  if (sec_abiflags->flags2 != 0)
    gold_warning(_("%s: Unexpected flag in the flags2 field of "
                   ".MIPS.abiflags (0x%x)"), relobj->name().c_str(),
                                             sec_abiflags->flags2);
  // Use abiflags from .MIPS.abiflags section.
  *abiflags = *sec_abiflags;
}

// Return the meaning of fp_abi, or "unknown" if not known.

template<int size, bool big_endian>
const char*
Target_mips<size, big_endian>::fp_abi_string(int fp)
{
  switch (fp)
    {
    case elfcpp::Val_GNU_MIPS_ABI_FP_DOUBLE:
      return "-mdouble-float";
    case elfcpp::Val_GNU_MIPS_ABI_FP_SINGLE:
      return "-msingle-float";
    case elfcpp::Val_GNU_MIPS_ABI_FP_SOFT:
      return "-msoft-float";
    case elfcpp::Val_GNU_MIPS_ABI_FP_OLD_64:
      return _("-mips32r2 -mfp64 (12 callee-saved)");
    case elfcpp::Val_GNU_MIPS_ABI_FP_XX:
      return "-mfpxx";
    case elfcpp::Val_GNU_MIPS_ABI_FP_64:
      return "-mgp32 -mfp64";
    case elfcpp::Val_GNU_MIPS_ABI_FP_64A:
      return "-mgp32 -mfp64 -mno-odd-spreg";
    default:
      return "unknown";
    }
}

// Select fp_abi.

template<int size, bool big_endian>
int
Target_mips<size, big_endian>::select_fp_abi(const std::string& name, int in_fp,
                                             int out_fp)
{
  if (in_fp == out_fp)
    return out_fp;

  if (out_fp == elfcpp::Val_GNU_MIPS_ABI_FP_ANY)
    return in_fp;
  else if (out_fp == elfcpp::Val_GNU_MIPS_ABI_FP_XX
           && (in_fp == elfcpp::Val_GNU_MIPS_ABI_FP_DOUBLE
               || in_fp == elfcpp::Val_GNU_MIPS_ABI_FP_64
               || in_fp == elfcpp::Val_GNU_MIPS_ABI_FP_64A))
    return in_fp;
  else if (in_fp == elfcpp::Val_GNU_MIPS_ABI_FP_XX
           && (out_fp == elfcpp::Val_GNU_MIPS_ABI_FP_DOUBLE
               || out_fp == elfcpp::Val_GNU_MIPS_ABI_FP_64
               || out_fp == elfcpp::Val_GNU_MIPS_ABI_FP_64A))
    return out_fp; // Keep the current setting.
  else if (out_fp == elfcpp::Val_GNU_MIPS_ABI_FP_64A
           && in_fp == elfcpp::Val_GNU_MIPS_ABI_FP_64)
    return in_fp;
  else if (in_fp == elfcpp::Val_GNU_MIPS_ABI_FP_64A
           && out_fp == elfcpp::Val_GNU_MIPS_ABI_FP_64)
    return out_fp; // Keep the current setting.
  else if (in_fp != elfcpp::Val_GNU_MIPS_ABI_FP_ANY)
    gold_warning(_("%s: FP ABI %s is incompatible with %s"), name.c_str(),
                 fp_abi_string(in_fp), fp_abi_string(out_fp));
  return out_fp;
}

// Merge attributes from input object.

template<int size, bool big_endian>
void
Target_mips<size, big_endian>::merge_obj_attributes(const std::string& 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.
  if (this->attributes_section_data_ == NULL)
    {
      this->attributes_section_data_ = new Attributes_section_data(*pasd);
      return;
    }

  Object_attribute* out_attr = this->attributes_section_data_->known_attributes(
      Object_attribute::OBJ_ATTR_GNU);

  out_attr[elfcpp::Tag_GNU_MIPS_ABI_FP].set_type(1);
  out_attr[elfcpp::Tag_GNU_MIPS_ABI_FP].set_int_value(this->abiflags_->fp_abi);

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

// Merge abiflags from input object.

template<int size, bool big_endian>
void
Target_mips<size, big_endian>::merge_obj_abiflags(const std::string& name,
    Mips_abiflags<big_endian>* in_abiflags)
{
  // If output has no abiflags, just copy.
  if (this->abiflags_ == NULL)
  {
    this->abiflags_ = new Mips_abiflags<big_endian>(*in_abiflags);
    return;
  }

  this->abiflags_->fp_abi = this->select_fp_abi(name, in_abiflags->fp_abi,
                                                this->abiflags_->fp_abi);

  // Merge abiflags.
  this->abiflags_->isa_level = std::max(this->abiflags_->isa_level,
                                        in_abiflags->isa_level);
  this->abiflags_->isa_rev = std::max(this->abiflags_->isa_rev,
                                      in_abiflags->isa_rev);
  this->abiflags_->gpr_size = std::max(this->abiflags_->gpr_size,
                                       in_abiflags->gpr_size);
  this->abiflags_->cpr1_size = std::max(this->abiflags_->cpr1_size,
                                        in_abiflags->cpr1_size);
  this->abiflags_->cpr2_size = std::max(this->abiflags_->cpr2_size,
                                        in_abiflags->cpr2_size);
  this->abiflags_->ases |= in_abiflags->ases;
  this->abiflags_->flags1 |= in_abiflags->flags1;
}

// Check whether machine EXTENSION is an extension of machine BASE.
template<int size, bool big_endian>
bool
Target_mips<size, big_endian>::mips_mach_extends(unsigned int base,
                                                 unsigned int extension)
{
  if (extension == base)
    return true;

  if ((base == mach_mipsisa32)
      && this->mips_mach_extends(mach_mipsisa64, extension))
    return true;

  if ((base == mach_mipsisa32r2)
      && this->mips_mach_extends(mach_mipsisa64r2, extension))
    return true;

  for (unsigned int i = 0; i < this->mips_mach_extensions_.size(); ++i)
    if (extension == this->mips_mach_extensions_[i].first)
      {
        extension = this->mips_mach_extensions_[i].second;
        if (extension == base)
          return true;
      }

  return false;
}

// Merge file header flags from input object.

template<int size, bool big_endian>
void
Target_mips<size, big_endian>::merge_obj_e_flags(const std::string& name,
                                                 elfcpp::Elf_Word in_flags)
{
  // If flags are not set yet, just copy them.
  if (!this->are_processor_specific_flags_set())
    {
      this->set_processor_specific_flags(in_flags);
      this->mach_ = this->elf_mips_mach(in_flags);
      return;
    }

  elfcpp::Elf_Word new_flags = in_flags;
  elfcpp::Elf_Word old_flags = this->processor_specific_flags();
  elfcpp::Elf_Word merged_flags = this->processor_specific_flags();
  merged_flags |= new_flags & elfcpp::EF_MIPS_NOREORDER;

  // Check flag compatibility.
  new_flags &= ~elfcpp::EF_MIPS_NOREORDER;
  old_flags &= ~elfcpp::EF_MIPS_NOREORDER;

  // Some IRIX 6 BSD-compatibility objects have this bit set.  It
  // doesn't seem to matter.
  new_flags &= ~elfcpp::EF_MIPS_XGOT;
  old_flags &= ~elfcpp::EF_MIPS_XGOT;

  // MIPSpro generates ucode info in n64 objects.  Again, we should
  // just be able to ignore this.
  new_flags &= ~elfcpp::EF_MIPS_UCODE;
  old_flags &= ~elfcpp::EF_MIPS_UCODE;

  if (new_flags == old_flags)
    {
      this->set_processor_specific_flags(merged_flags);
      return;
    }

  if (((new_flags & (elfcpp::EF_MIPS_PIC | elfcpp::EF_MIPS_CPIC)) != 0)
      != ((old_flags & (elfcpp::EF_MIPS_PIC | elfcpp::EF_MIPS_CPIC)) != 0))
    gold_warning(_("%s: linking abicalls files with non-abicalls files"),
                 name.c_str());

  if (new_flags & (elfcpp::EF_MIPS_PIC | elfcpp::EF_MIPS_CPIC))
    merged_flags |= elfcpp::EF_MIPS_CPIC;
  if (!(new_flags & elfcpp::EF_MIPS_PIC))
    merged_flags &= ~elfcpp::EF_MIPS_PIC;

  new_flags &= ~(elfcpp::EF_MIPS_PIC | elfcpp::EF_MIPS_CPIC);
  old_flags &= ~(elfcpp::EF_MIPS_PIC | elfcpp::EF_MIPS_CPIC);

  // Compare the ISAs.
  if (mips_32bit_flags(old_flags) != mips_32bit_flags(new_flags))
    gold_error(_("%s: linking 32-bit code with 64-bit code"), name.c_str());
  else if (!this->mips_mach_extends(this->elf_mips_mach(in_flags), this->mach_))
    {
      // Output ISA isn't the same as, or an extension of, input ISA.
      if (this->mips_mach_extends(this->mach_, this->elf_mips_mach(in_flags)))
        {
          // Copy the architecture info from input object to output.  Also copy
          // the 32-bit flag (if set) so that we continue to recognise
          // output as a 32-bit binary.
          this->mach_ = this->elf_mips_mach(in_flags);
          merged_flags &= ~(elfcpp::EF_MIPS_ARCH | elfcpp::EF_MIPS_MACH);
          merged_flags |= (new_flags & (elfcpp::EF_MIPS_ARCH
                           | elfcpp::EF_MIPS_MACH | elfcpp::EF_MIPS_32BITMODE));

          // Update the ABI flags isa_level, isa_rev, isa_ext fields.
          this->update_abiflags_isa(name, merged_flags, this->abiflags_);

          // Copy across the ABI flags if output doesn't use them
          // and if that was what caused us to treat input object as 32-bit.
          if ((old_flags & elfcpp::EF_MIPS_ABI) == 0
              && this->mips_32bit_flags(new_flags)
              && !this->mips_32bit_flags(new_flags & ~elfcpp::EF_MIPS_ABI))
            merged_flags |= new_flags & elfcpp::EF_MIPS_ABI;
        }
      else
        // The ISAs aren't compatible.
        gold_error(_("%s: linking %s module with previous %s modules"),
                   name.c_str(), this->elf_mips_mach_name(in_flags),
                   this->elf_mips_mach_name(merged_flags));
    }

  new_flags &= (~(elfcpp::EF_MIPS_ARCH | elfcpp::EF_MIPS_MACH
                | elfcpp::EF_MIPS_32BITMODE));
  old_flags &= (~(elfcpp::EF_MIPS_ARCH | elfcpp::EF_MIPS_MACH
                | elfcpp::EF_MIPS_32BITMODE));

  // Compare ABIs.
  if ((new_flags & elfcpp::EF_MIPS_ABI) != (old_flags & elfcpp::EF_MIPS_ABI))
    {
      // Only error if both are set (to different values).
      if ((new_flags & elfcpp::EF_MIPS_ABI)
           && (old_flags & elfcpp::EF_MIPS_ABI))
        gold_error(_("%s: ABI mismatch: linking %s module with "
                     "previous %s modules"), name.c_str(),
                   this->elf_mips_abi_name(in_flags),
                   this->elf_mips_abi_name(merged_flags));

      new_flags &= ~elfcpp::EF_MIPS_ABI;
      old_flags &= ~elfcpp::EF_MIPS_ABI;
    }

  // Compare ASEs.  Forbid linking MIPS16 and microMIPS ASE modules together
  // and allow arbitrary mixing of the remaining ASEs (retain the union).
  if ((new_flags & elfcpp::EF_MIPS_ARCH_ASE)
      != (old_flags & elfcpp::EF_MIPS_ARCH_ASE))
    {
      int old_micro = old_flags & elfcpp::EF_MIPS_ARCH_ASE_MICROMIPS;
      int new_micro = new_flags & elfcpp::EF_MIPS_ARCH_ASE_MICROMIPS;
      int old_m16 = old_flags & elfcpp::EF_MIPS_ARCH_ASE_M16;
      int new_m16 = new_flags & elfcpp::EF_MIPS_ARCH_ASE_M16;
      int micro_mis = old_m16 && new_micro;
      int m16_mis = old_micro && new_m16;

      if (m16_mis || micro_mis)
        gold_error(_("%s: ASE mismatch: linking %s module with "
                     "previous %s modules"), name.c_str(),
                   m16_mis ? "MIPS16" : "microMIPS",
                   m16_mis ? "microMIPS" : "MIPS16");

      merged_flags |= new_flags & elfcpp::EF_MIPS_ARCH_ASE;

      new_flags &= ~ elfcpp::EF_MIPS_ARCH_ASE;
      old_flags &= ~ elfcpp::EF_MIPS_ARCH_ASE;
    }

  // Compare NaN encodings.
  if ((new_flags & elfcpp::EF_MIPS_NAN2008) != (old_flags & elfcpp::EF_MIPS_NAN2008))
    {
      gold_error(_("%s: linking %s module with previous %s modules"),
                 name.c_str(),
                 (new_flags & elfcpp::EF_MIPS_NAN2008
                  ? "-mnan=2008" : "-mnan=legacy"),
                 (old_flags & elfcpp::EF_MIPS_NAN2008
                  ? "-mnan=2008" : "-mnan=legacy"));

      new_flags &= ~elfcpp::EF_MIPS_NAN2008;
      old_flags &= ~elfcpp::EF_MIPS_NAN2008;
    }

  // Compare FP64 state.
  if ((new_flags & elfcpp::EF_MIPS_FP64) != (old_flags & elfcpp::EF_MIPS_FP64))
    {
      gold_error(_("%s: linking %s module with previous %s modules"),
                 name.c_str(),
                 (new_flags & elfcpp::EF_MIPS_FP64
                  ? "-mfp64" : "-mfp32"),
                 (old_flags & elfcpp::EF_MIPS_FP64
                  ? "-mfp64" : "-mfp32"));

      new_flags &= ~elfcpp::EF_MIPS_FP64;
      old_flags &= ~elfcpp::EF_MIPS_FP64;
    }

  // Warn about any other mismatches.
  if (new_flags != old_flags)
    gold_error(_("%s: uses different e_flags (0x%x) fields than previous "
                 "modules (0x%x)"), name.c_str(), new_flags, old_flags);

  this->set_processor_specific_flags(merged_flags);
}

// Adjust ELF file header.

template<int size, bool big_endian>
void
Target_mips<size, big_endian>::do_adjust_elf_header(
    unsigned char* view,
    int len)
{
  gold_assert(len == elfcpp::Elf_sizes<size>::ehdr_size);

  elfcpp::Ehdr<size, big_endian> ehdr(view);
  unsigned char e_ident[elfcpp::EI_NIDENT];
  elfcpp::Elf_Word flags = this->processor_specific_flags();
  memcpy(e_ident, ehdr.get_e_ident(), elfcpp::EI_NIDENT);

  unsigned char ei_abiversion = 0;
  elfcpp::Elf_Half type = ehdr.get_e_type();
  if (type == elfcpp::ET_EXEC
      && parameters->options().copyreloc()
      && (flags & (elfcpp::EF_MIPS_PIC | elfcpp::EF_MIPS_CPIC))
          == elfcpp::EF_MIPS_CPIC)
    ei_abiversion = 1;

  if (this->abiflags_ != NULL
      && (this->abiflags_->fp_abi == elfcpp::Val_GNU_MIPS_ABI_FP_64
          || this->abiflags_->fp_abi == elfcpp::Val_GNU_MIPS_ABI_FP_64A))
    ei_abiversion = 3;

  e_ident[elfcpp::EI_ABIVERSION] = ei_abiversion;
  elfcpp::Ehdr_write<size, big_endian> oehdr(view);
  oehdr.put_e_ident(e_ident);

  if (this->entry_symbol_is_compressed_)
    oehdr.put_e_entry(ehdr.get_e_entry() + 1);
}

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

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

// Finalize the sections.

template <int size, bool big_endian>
void
Target_mips<size, big_endian>::do_finalize_sections(Layout* layout,
                                        const Input_objects* input_objects,
                                        Symbol_table* symtab)
{
  const bool relocatable = parameters->options().relocatable();

  // Add +1 to MIPS16 and microMIPS init_ and _fini symbols so that DT_INIT and
  // DT_FINI have correct values.
  Mips_symbol<size>* init = static_cast<Mips_symbol<size>*>(
      symtab->lookup(parameters->options().init()));
  if (init != NULL && (init->is_mips16() || init->is_micromips()))
    init->set_value(init->value() | 1);
  Mips_symbol<size>* fini = static_cast<Mips_symbol<size>*>(
      symtab->lookup(parameters->options().fini()));
  if (fini != NULL && (fini->is_mips16() || fini->is_micromips()))
    fini->set_value(fini->value() | 1);

  // Check whether the entry symbol is mips16 or micromips.  This is needed to
  // adjust entry address in ELF header.
  Mips_symbol<size>* entry =
    static_cast<Mips_symbol<size>*>(symtab->lookup(this->entry_symbol_name()));
  this->entry_symbol_is_compressed_ = (entry != NULL && (entry->is_mips16()
                                       || entry->is_micromips()));

  if (!parameters->doing_static_link()
      && (strcmp(parameters->options().hash_style(), "gnu") == 0
          || strcmp(parameters->options().hash_style(), "both") == 0))
    {
      // .gnu.hash and the MIPS ABI require .dynsym to be sorted in different
      // ways.  .gnu.hash needs symbols to be grouped by hash code whereas the
      // MIPS ABI requires a mapping between the GOT and the symbol table.
      gold_error(".gnu.hash is incompatible with the MIPS ABI");
    }

  // Check whether the final section that was scanned has HI16 or GOT16
  // relocations without the corresponding LO16 part.
  if (this->got16_addends_.size() > 0)
      gold_error("Can't find matching LO16 reloc");

  Valtype gprmask = 0;
  Valtype cprmask1 = 0;
  Valtype cprmask2 = 0;
  Valtype cprmask3 = 0;
  Valtype cprmask4 = 0;
  bool has_reginfo_section = false;

  for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
       p != input_objects->relobj_end();
       ++p)
    {
      Mips_relobj<size, big_endian>* relobj =
        Mips_relobj<size, big_endian>::as_mips_relobj(*p);

      // Check for any mips16 stub sections that we can discard.
      if (!relocatable)
        relobj->discard_mips16_stub_sections(symtab);

      if (!relobj->merge_processor_specific_data())
        continue;

      // Merge .reginfo contents of input objects.
      if (relobj->has_reginfo_section())
        {
          has_reginfo_section = true;
          gprmask |= relobj->gprmask();
          cprmask1 |= relobj->cprmask1();
          cprmask2 |= relobj->cprmask2();
          cprmask3 |= relobj->cprmask3();
          cprmask4 |= relobj->cprmask4();
        }

      // Merge processor specific flags.
      Mips_abiflags<big_endian> in_abiflags;

      this->create_abiflags(relobj, &in_abiflags);
      this->merge_obj_e_flags(relobj->name(),
                              relobj->processor_specific_flags());
      this->merge_obj_abiflags(relobj->name(), &in_abiflags);
      this->merge_obj_attributes(relobj->name(),
                                 relobj->attributes_section_data());
    }

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

  // Create .MIPS.abiflags output section if there is an input section.
  if (this->has_abiflags_section_)
    {
      Mips_output_section_abiflags<size, big_endian>* abiflags_section =
        new Mips_output_section_abiflags<size, big_endian>(*this->abiflags_);

      Output_section* os =
        layout->add_output_section_data(".MIPS.abiflags",
                                        elfcpp::SHT_MIPS_ABIFLAGS,
                                        elfcpp::SHF_ALLOC,
                                        abiflags_section, ORDER_INVALID, false);

      if (!relocatable && os != NULL)
        {
          Output_segment* abiflags_segment =
            layout->make_output_segment(elfcpp::PT_MIPS_ABIFLAGS, elfcpp::PF_R);
          abiflags_segment->add_output_section_to_nonload(os, elfcpp::PF_R);
        }
    }

  if (has_reginfo_section && !parameters->options().gc_sections())
    {
      // Create .reginfo output section.
      Mips_output_section_reginfo<size, big_endian>* reginfo_section =
        new Mips_output_section_reginfo<size, big_endian>(this, gprmask,
                                                          cprmask1, cprmask2,
                                                          cprmask3, cprmask4);

      Output_section* os =
        layout->add_output_section_data(".reginfo", elfcpp::SHT_MIPS_REGINFO,
                                        elfcpp::SHF_ALLOC, reginfo_section,
                                        ORDER_INVALID, false);

      if (!relocatable && os != NULL)
        {
          Output_segment* reginfo_segment =
            layout->make_output_segment(elfcpp::PT_MIPS_REGINFO,
                                        elfcpp::PF_R);
          reginfo_segment->add_output_section_to_nonload(os, elfcpp::PF_R);
        }
    }

  if (this->plt_ != NULL)
    {
      // Set final PLT offsets for symbols.
      this->plt_section()->set_plt_offsets();

      // Define _PROCEDURE_LINKAGE_TABLE_ at the start of the .plt section.
      // Set STO_MICROMIPS flag if the output has microMIPS code, but only if
      // there are no standard PLT entries present.
      unsigned char nonvis = 0;
      if (this->is_output_micromips()
          && !this->plt_section()->has_standard_entries())
        nonvis = elfcpp::STO_MICROMIPS >> 2;
      symtab->define_in_output_data("_PROCEDURE_LINKAGE_TABLE_", NULL,
                                    Symbol_table::PREDEFINED,
                                    this->plt_,
                                    0, 0, elfcpp::STT_FUNC,
                                    elfcpp::STB_LOCAL,
                                    elfcpp::STV_DEFAULT, nonvis,
                                    false, false);
    }

  if (this->mips_stubs_ != NULL)
    {
      // Define _MIPS_STUBS_ at the start of the .MIPS.stubs section.
      unsigned char nonvis = 0;
      if (this->is_output_micromips())
        nonvis = elfcpp::STO_MICROMIPS >> 2;
      symtab->define_in_output_data("_MIPS_STUBS_", NULL,
                                    Symbol_table::PREDEFINED,
                                    this->mips_stubs_,
                                    0, 0, elfcpp::STT_FUNC,
                                    elfcpp::STB_LOCAL,
                                    elfcpp::STV_DEFAULT, nonvis,
                                    false, false);
    }

  if (!relocatable && !parameters->doing_static_link())
    // In case there is no .got section, create one.
    this->got_section(symtab, layout);

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

  // Set _gp value.
  this->set_gp(layout, symtab);

  // Emit dynamic relocs.
  for (typename std::vector<Dyn_reloc>::iterator p = this->dyn_relocs_.begin();
       p != this->dyn_relocs_.end();
       ++p)
    p->emit(this->rel_dyn_section(layout), this->got_section(), symtab);

  if (this->has_got_section())
    this->got_section()->lay_out_got(layout, symtab, input_objects);

  if (this->mips_stubs_ != NULL)
    this->mips_stubs_->set_needs_dynsym_value();

  // Check for functions that might need $25 to be valid on entry.
  // TODO(sasa): Can we do this without iterating over all symbols?
  typedef Symbol_visitor_check_symbols<size, big_endian> Symbol_visitor;
  symtab->for_all_symbols<size, Symbol_visitor>(Symbol_visitor(this, layout,
                                                               symtab));

  // Add NULL segment.
  if (!relocatable)
    layout->make_output_segment(elfcpp::PT_NULL, 0);

  // Fill in some more dynamic tags.
  // TODO(sasa): Add more dynamic tags.
  const Reloc_section* rel_plt = (this->plt_ == NULL
                                  ? NULL : this->plt_->rel_plt());
  layout->add_target_dynamic_tags(true, this->got_, rel_plt,
                                  this->rel_dyn_, true, false);

  Output_data_dynamic* const odyn = layout->dynamic_data();
  if (odyn != NULL
      && !relocatable
      && !parameters->doing_static_link())
  {
    unsigned int d_val;
    // This element holds a 32-bit version id for the Runtime
    // Linker Interface.  This will start at integer value 1.
    d_val = 0x01;
    odyn->add_constant(elfcpp::DT_MIPS_RLD_VERSION, d_val);

    // Dynamic flags
    d_val = elfcpp::RHF_NOTPOT;
    odyn->add_constant(elfcpp::DT_MIPS_FLAGS, d_val);

    // Save layout for using when emitting custom dynamic tags.
    this->layout_ = layout;

    // This member holds the base address of the segment.
    odyn->add_custom(elfcpp::DT_MIPS_BASE_ADDRESS);

    // This member holds the number of entries in the .dynsym section.
    odyn->add_custom(elfcpp::DT_MIPS_SYMTABNO);

    // This member holds the index of the first dynamic symbol
    // table entry that corresponds to an entry in the global offset table.
    odyn->add_custom(elfcpp::DT_MIPS_GOTSYM);

    // This member holds the number of local GOT entries.
    odyn->add_constant(elfcpp::DT_MIPS_LOCAL_GOTNO,
                       this->got_->get_local_gotno());

    if (this->plt_ != NULL)
      // DT_MIPS_PLTGOT dynamic tag
      odyn->add_section_address(elfcpp::DT_MIPS_PLTGOT, this->got_plt_);

    if (!parameters->options().shared())
      {
        this->rld_map_ = new Output_data_zero_fill(size / 8, size / 8);

        layout->add_output_section_data(".rld_map", elfcpp::SHT_PROGBITS,
                                        (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
                                        this->rld_map_, ORDER_INVALID, false);

        // __RLD_MAP will be filled in by the runtime loader to contain
        // a pointer to the _r_debug structure.
        Symbol* rld_map = symtab->define_in_output_data("__RLD_MAP", NULL,
                                            Symbol_table::PREDEFINED,
                                            this->rld_map_,
                                            0, 0, elfcpp::STT_OBJECT,
                                            elfcpp::STB_GLOBAL,
                                            elfcpp::STV_DEFAULT, 0,
                                            false, false);

        if (!rld_map->is_forced_local())
          rld_map->set_needs_dynsym_entry();

        if (!parameters->options().pie())
          // This member holds the absolute address of the debug pointer.
          odyn->add_section_address(elfcpp::DT_MIPS_RLD_MAP, this->rld_map_);
        else
          // This member holds the offset to the debug pointer,
          // relative to the address of the tag.
          odyn->add_custom(elfcpp::DT_MIPS_RLD_MAP_REL);
      }
  }
}

// Get the custom dynamic tag value.
template<int size, bool big_endian>
unsigned int
Target_mips<size, big_endian>::do_dynamic_tag_custom_value(elfcpp::DT tag) const
{
  switch (tag)
    {
    case elfcpp::DT_MIPS_BASE_ADDRESS:
      {
        // The base address of the segment.
        // At this point, the segment list has been sorted into final order,
        // so just return vaddr of the first readable PT_LOAD segment.
        Output_segment* seg =
          this->layout_->find_output_segment(elfcpp::PT_LOAD, elfcpp::PF_R, 0);
        gold_assert(seg != NULL);
        return seg->vaddr();
      }

    case elfcpp::DT_MIPS_SYMTABNO:
      // The number of entries in the .dynsym section.
      return this->get_dt_mips_symtabno();

    case elfcpp::DT_MIPS_GOTSYM:
      {
        // The index of the first dynamic symbol table entry that corresponds
        // to an entry in the GOT.
        if (this->got_->first_global_got_dynsym_index() != -1U)
          return this->got_->first_global_got_dynsym_index();
        else
          // In case if we don't have global GOT symbols we default to setting
          // DT_MIPS_GOTSYM to the same value as DT_MIPS_SYMTABNO.
          return this->get_dt_mips_symtabno();
      }

    case elfcpp::DT_MIPS_RLD_MAP_REL:
      {
        // The MIPS_RLD_MAP_REL tag stores the offset to the debug pointer,
        // relative to the address of the tag.
        Output_data_dynamic* const odyn = this->layout_->dynamic_data();
        unsigned int entry_offset =
          odyn->get_entry_offset(elfcpp::DT_MIPS_RLD_MAP_REL);
        gold_assert(entry_offset != -1U);
        return this->rld_map_->address() - (odyn->address() + entry_offset);
      }
    default:
      gold_error(_("Unknown dynamic tag 0x%x"), (unsigned int)tag);
    }

  return (unsigned int)-1;
}

// Relocate section data.

template<int size, bool big_endian>
void
Target_mips<size, big_endian>::relocate_section(
                        const Relocate_info<size, big_endian>* relinfo,
                        unsigned int sh_type,
                        const unsigned char* prelocs,
                        size_t reloc_count,
                        Output_section* output_section,
                        bool needs_special_offset_handling,
                        unsigned char* view,
                        Mips_address address,
                        section_size_type view_size,
                        const Reloc_symbol_changes* reloc_symbol_changes)
{
  typedef Target_mips<size, big_endian> Mips;
  typedef typename Target_mips<size, big_endian>::Relocate Mips_relocate;

  if (sh_type == elfcpp::SHT_REL)
    {
      typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>
	  Classify_reloc;

      gold::relocate_section<size, big_endian, Mips, Mips_relocate,
			     gold::Default_comdat_behavior, Classify_reloc>(
	relinfo,
	this,
	prelocs,
	reloc_count,
	output_section,
	needs_special_offset_handling,
	view,
	address,
	view_size,
	reloc_symbol_changes);
    }
  else if (sh_type == elfcpp::SHT_RELA)
    {
      typedef Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
	  Classify_reloc;

      gold::relocate_section<size, big_endian, Mips, Mips_relocate,
			     gold::Default_comdat_behavior, Classify_reloc>(
	relinfo,
	this,
	prelocs,
	reloc_count,
	output_section,
	needs_special_offset_handling,
	view,
	address,
	view_size,
	reloc_symbol_changes);
    }
}

// Return the size of a relocation while scanning during a relocatable
// link.

unsigned int
mips_get_size_for_reloc(unsigned int r_type, Relobj* object)
{
  switch (r_type)
    {
    case elfcpp::R_MIPS_NONE:
    case elfcpp::R_MIPS_TLS_DTPMOD64:
    case elfcpp::R_MIPS_TLS_DTPREL64:
    case elfcpp::R_MIPS_TLS_TPREL64:
      return 0;

    case elfcpp::R_MIPS_32:
    case elfcpp::R_MIPS_TLS_DTPMOD32:
    case elfcpp::R_MIPS_TLS_DTPREL32:
    case elfcpp::R_MIPS_TLS_TPREL32:
    case elfcpp::R_MIPS_REL32:
    case elfcpp::R_MIPS_PC32:
    case elfcpp::R_MIPS_GPREL32:
    case elfcpp::R_MIPS_JALR:
    case elfcpp::R_MIPS_EH:
      return 4;

    case elfcpp::R_MIPS_16:
    case elfcpp::R_MIPS_HI16:
    case elfcpp::R_MIPS_LO16:
    case elfcpp::R_MIPS_HIGHER:
    case elfcpp::R_MIPS_HIGHEST:
    case elfcpp::R_MIPS_GPREL16:
    case elfcpp::R_MIPS16_HI16:
    case elfcpp::R_MIPS16_LO16:
    case elfcpp::R_MIPS_PC16:
    case elfcpp::R_MIPS_PCHI16:
    case elfcpp::R_MIPS_PCLO16:
    case elfcpp::R_MIPS_GOT16:
    case elfcpp::R_MIPS16_GOT16:
    case elfcpp::R_MIPS_CALL16:
    case elfcpp::R_MIPS16_CALL16:
    case elfcpp::R_MIPS_GOT_HI16:
    case elfcpp::R_MIPS_CALL_HI16:
    case elfcpp::R_MIPS_GOT_LO16:
    case elfcpp::R_MIPS_CALL_LO16:
    case elfcpp::R_MIPS_TLS_DTPREL_HI16:
    case elfcpp::R_MIPS_TLS_DTPREL_LO16:
    case elfcpp::R_MIPS_TLS_TPREL_HI16:
    case elfcpp::R_MIPS_TLS_TPREL_LO16:
    case elfcpp::R_MIPS16_GPREL:
    case elfcpp::R_MIPS_GOT_DISP:
    case elfcpp::R_MIPS_LITERAL:
    case elfcpp::R_MIPS_GOT_PAGE:
    case elfcpp::R_MIPS_GOT_OFST:
    case elfcpp::R_MIPS_TLS_GD:
    case elfcpp::R_MIPS_TLS_LDM:
    case elfcpp::R_MIPS_TLS_GOTTPREL:
      return 2;

    // These relocations are not byte sized
    case elfcpp::R_MIPS_26:
    case elfcpp::R_MIPS16_26:
    case elfcpp::R_MIPS_PC21_S2:
    case elfcpp::R_MIPS_PC26_S2:
    case elfcpp::R_MIPS_PC18_S3:
    case elfcpp::R_MIPS_PC19_S2:
      return 4;

    case elfcpp::R_MIPS_COPY:
    case elfcpp::R_MIPS_JUMP_SLOT:
      object->error(_("unexpected reloc %u in object file"), r_type);
      return 0;

    default:
      object->error(_("unsupported reloc %u in object file"), r_type);
      return 0;
  }
}

// Scan the relocs during a relocatable link.

template<int size, bool big_endian>
void
Target_mips<size, big_endian>::scan_relocatable_relocs(
                        Symbol_table* symtab,
                        Layout* layout,
                        Sized_relobj_file<size, big_endian>* object,
                        unsigned int data_shndx,
                        unsigned int sh_type,
                        const unsigned char* prelocs,
                        size_t reloc_count,
                        Output_section* output_section,
                        bool needs_special_offset_handling,
                        size_t local_symbol_count,
                        const unsigned char* plocal_symbols,
                        Relocatable_relocs* rr)
{
  if (sh_type == elfcpp::SHT_REL)
    {
      typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>
          Classify_reloc;
      typedef Mips_scan_relocatable_relocs<big_endian, Classify_reloc>
          Scan_relocatable_relocs;

      gold::scan_relocatable_relocs<size, big_endian, Scan_relocatable_relocs>(
        symtab,
        layout,
        object,
        data_shndx,
        prelocs,
        reloc_count,
        output_section,
        needs_special_offset_handling,
        local_symbol_count,
        plocal_symbols,
        rr);
    }
  else if (sh_type == elfcpp::SHT_RELA)
    {
      typedef Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
          Classify_reloc;
      typedef Mips_scan_relocatable_relocs<big_endian, Classify_reloc>
          Scan_relocatable_relocs;

      gold::scan_relocatable_relocs<size, big_endian, Scan_relocatable_relocs>(
        symtab,
        layout,
        object,
        data_shndx,
        prelocs,
        reloc_count,
        output_section,
        needs_special_offset_handling,
        local_symbol_count,
        plocal_symbols,
        rr);
    }
  else
    gold_unreachable();
}

// Scan the relocs for --emit-relocs.

template<int size, bool big_endian>
void
Target_mips<size, big_endian>::emit_relocs_scan(
    Symbol_table* symtab,
    Layout* layout,
    Sized_relobj_file<size, big_endian>* object,
    unsigned int data_shndx,
    unsigned int sh_type,
    const unsigned char* prelocs,
    size_t reloc_count,
    Output_section* output_section,
    bool needs_special_offset_handling,
    size_t local_symbol_count,
    const unsigned char* plocal_syms,
    Relocatable_relocs* rr)
{
  if (sh_type == elfcpp::SHT_REL)
    {
      typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>
          Classify_reloc;
      typedef gold::Default_emit_relocs_strategy<Classify_reloc>
          Emit_relocs_strategy;

      gold::scan_relocatable_relocs<size, big_endian, Emit_relocs_strategy>(
        symtab,
        layout,
        object,
        data_shndx,
        prelocs,
        reloc_count,
        output_section,
        needs_special_offset_handling,
        local_symbol_count,
        plocal_syms,
        rr);
    }
  else if (sh_type == elfcpp::SHT_RELA)
    {
      typedef Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
          Classify_reloc;
      typedef gold::Default_emit_relocs_strategy<Classify_reloc>
          Emit_relocs_strategy;

      gold::scan_relocatable_relocs<size, big_endian, Emit_relocs_strategy>(
        symtab,
        layout,
        object,
        data_shndx,
        prelocs,
        reloc_count,
        output_section,
        needs_special_offset_handling,
        local_symbol_count,
        plocal_syms,
        rr);
    }
  else
    gold_unreachable();
}

// Emit relocations for a section.

template<int size, bool big_endian>
void
Target_mips<size, big_endian>::relocate_relocs(
                        const Relocate_info<size, big_endian>* relinfo,
                        unsigned int sh_type,
                        const unsigned char* prelocs,
                        size_t reloc_count,
                        Output_section* output_section,
                        typename elfcpp::Elf_types<size>::Elf_Off
                          offset_in_output_section,
                        unsigned char* view,
                        Mips_address view_address,
                        section_size_type view_size,
                        unsigned char* reloc_view,
                        section_size_type reloc_view_size)
{
  if (sh_type == elfcpp::SHT_REL)
    {
      typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>
          Classify_reloc;

      gold::relocate_relocs<size, big_endian, Classify_reloc>(
        relinfo,
        prelocs,
        reloc_count,
        output_section,
        offset_in_output_section,
        view,
        view_address,
        view_size,
        reloc_view,
        reloc_view_size);
    }
  else if (sh_type == elfcpp::SHT_RELA)
    {
      typedef Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
          Classify_reloc;

      gold::relocate_relocs<size, big_endian, Classify_reloc>(
        relinfo,
        prelocs,
        reloc_count,
        output_section,
        offset_in_output_section,
        view,
        view_address,
        view_size,
        reloc_view,
        reloc_view_size);
    }
  else
    gold_unreachable();
}

// Perform target-specific processing in a relocatable link.  This is
// only used if we use the relocation strategy RELOC_SPECIAL.

template<int size, bool big_endian>
void
Target_mips<size, big_endian>::relocate_special_relocatable(
    const Relocate_info<size, big_endian>* relinfo,
    unsigned int sh_type,
    const unsigned char* preloc_in,
    size_t relnum,
    Output_section* output_section,
    typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
    unsigned char* view,
    Mips_address 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, size, big_endian>::Reloc
    Reltype;
  typedef typename Reloc_types<elfcpp::SHT_REL, size, big_endian>::Reloc_write
    Reltype_write;

  typedef Mips_relocate_functions<size, big_endian> Reloc_funcs;

  const Mips_address invalid_address = static_cast<Mips_address>(0) - 1;

  Mips_relobj<size, big_endian>* object =
    Mips_relobj<size, big_endian>::as_mips_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<size>(r_info);
  const unsigned int r_type = elfcpp::elf_r_type<size>(r_info);

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

  Mips_address offset = reloc.get_r_offset();
  Mips_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, Mips_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.
  Valtype calculated_value = 0;
  const Symbol_value<size>* psymval = object->local_symbol(r_sym);

  unsigned char* paddend = view + offset;
  typename Reloc_funcs::Status reloc_status = Reloc_funcs::STATUS_OKAY;
  switch (r_type)
    {
    case elfcpp::R_MIPS_26:
      reloc_status = Reloc_funcs::rel26(paddend, object, psymval,
          offset_in_output_section, true, 0, sh_type == elfcpp::SHT_REL, NULL,
          false /*TODO(sasa): cross mode jump*/, r_type, this->jal_to_bal(),
          false, &calculated_value);
      break;

    default:
      gold_unreachable();
    }

  // Report any errors.
  switch (reloc_status)
    {
    case Reloc_funcs::STATUS_OKAY:
      break;
    case Reloc_funcs::STATUS_OVERFLOW:
      gold_error_at_location(relinfo, relnum, reloc.get_r_offset(),
			     _("relocation overflow: "
			       "%u against local symbol %u in %s"),
			     r_type, r_sym, object->name().c_str());
      break;
    case Reloc_funcs::STATUS_BAD_RELOC:
      gold_error_at_location(relinfo, relnum, reloc.get_r_offset(),
        _("unexpected opcode while processing relocation"));
      break;
    default:
      gold_unreachable();
    }
}

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

template<int size, bool big_endian>
tls::Tls_optimization
Target_mips<size, big_endian>::optimize_tls_reloc(bool, int)
{
  // FIXME: Currently we do not do any TLS optimization.
  return tls::TLSOPT_NONE;
}

// Scan a relocation for a local symbol.

template<int size, bool big_endian>
inline void
Target_mips<size, big_endian>::Scan::local(
                        Symbol_table* symtab,
                        Layout* layout,
                        Target_mips<size, big_endian>* target,
                        Sized_relobj_file<size, big_endian>* object,
                        unsigned int data_shndx,
                        Output_section* output_section,
                        const Relatype* rela,
                        const Reltype* rel,
                        unsigned int rel_type,
                        unsigned int r_type,
                        const elfcpp::Sym<size, big_endian>& lsym,
                        bool is_discarded)
{
  if (is_discarded)
    return;

  Mips_address r_offset;
  unsigned int r_sym;
  typename elfcpp::Elf_types<size>::Elf_Swxword r_addend;

  if (rel_type == elfcpp::SHT_RELA)
    {
      r_offset = rela->get_r_offset();
      r_sym = Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>::
	  get_r_sym(rela);
      r_addend = rela->get_r_addend();
    }
  else
    {
      r_offset = rel->get_r_offset();
      r_sym = Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>::
	  get_r_sym(rel);
      r_addend = 0;
    }

  Mips_relobj<size, big_endian>* mips_obj =
    Mips_relobj<size, big_endian>::as_mips_relobj(object);

  if (mips_obj->is_mips16_stub_section(data_shndx))
    {
      mips_obj->get_mips16_stub_section(data_shndx)
              ->new_local_reloc_found(r_type, r_sym);
    }

  if (r_type == elfcpp::R_MIPS_NONE)
    // R_MIPS_NONE is used in mips16 stub sections, to define the target of the
    // mips16 stub.
    return;

  if (!mips16_call_reloc(r_type)
      && !mips_obj->section_allows_mips16_refs(data_shndx))
    // This reloc would need to refer to a MIPS16 hard-float stub, if
    // there is one.  We ignore MIPS16 stub sections and .pdr section when
    // looking for relocs that would need to refer to MIPS16 stubs.
    mips_obj->add_local_non_16bit_call(r_sym);

  if (r_type == elfcpp::R_MIPS16_26
      && !mips_obj->section_allows_mips16_refs(data_shndx))
    mips_obj->add_local_16bit_call(r_sym);

  switch (r_type)
    {
    case elfcpp::R_MIPS_GOT16:
    case elfcpp::R_MIPS_CALL16:
    case elfcpp::R_MIPS_CALL_HI16:
    case elfcpp::R_MIPS_CALL_LO16:
    case elfcpp::R_MIPS_GOT_HI16:
    case elfcpp::R_MIPS_GOT_LO16:
    case elfcpp::R_MIPS_GOT_PAGE:
    case elfcpp::R_MIPS_GOT_OFST:
    case elfcpp::R_MIPS_GOT_DISP:
    case elfcpp::R_MIPS_TLS_GOTTPREL:
    case elfcpp::R_MIPS_TLS_GD:
    case elfcpp::R_MIPS_TLS_LDM:
    case elfcpp::R_MIPS16_GOT16:
    case elfcpp::R_MIPS16_CALL16:
    case elfcpp::R_MIPS16_TLS_GOTTPREL:
    case elfcpp::R_MIPS16_TLS_GD:
    case elfcpp::R_MIPS16_TLS_LDM:
    case elfcpp::R_MICROMIPS_GOT16:
    case elfcpp::R_MICROMIPS_CALL16:
    case elfcpp::R_MICROMIPS_CALL_HI16:
    case elfcpp::R_MICROMIPS_CALL_LO16:
    case elfcpp::R_MICROMIPS_GOT_HI16:
    case elfcpp::R_MICROMIPS_GOT_LO16:
    case elfcpp::R_MICROMIPS_GOT_PAGE:
    case elfcpp::R_MICROMIPS_GOT_OFST:
    case elfcpp::R_MICROMIPS_GOT_DISP:
    case elfcpp::R_MICROMIPS_TLS_GOTTPREL:
    case elfcpp::R_MICROMIPS_TLS_GD:
    case elfcpp::R_MICROMIPS_TLS_LDM:
    case elfcpp::R_MIPS_EH:
      // We need a GOT section.
      target->got_section(symtab, layout);
      break;

    default:
      break;
    }

  if (call_lo16_reloc(r_type)
      || got_lo16_reloc(r_type)
      || got_disp_reloc(r_type)
      || eh_reloc(r_type))
    {
      // We may need a local GOT entry for this relocation.  We
      // don't count R_MIPS_GOT_PAGE because we can estimate the
      // maximum number of pages needed by looking at the size of
      // the segment.  Similar comments apply to R_MIPS*_GOT16 and
      // R_MIPS*_CALL16.  We don't count R_MIPS_GOT_HI16, or
      // R_MIPS_CALL_HI16 because these are always followed by an
      // R_MIPS_GOT_LO16 or R_MIPS_CALL_LO16.
      Mips_output_data_got<size, big_endian>* got =
        target->got_section(symtab, layout);
      bool is_section_symbol = lsym.get_st_type() == elfcpp::STT_SECTION;
      got->record_local_got_symbol(mips_obj, r_sym, r_addend, r_type, -1U,
                                   is_section_symbol);
    }

  switch (r_type)
    {
    case elfcpp::R_MIPS_CALL16:
    case elfcpp::R_MIPS16_CALL16:
    case elfcpp::R_MICROMIPS_CALL16:
      gold_error(_("CALL16 reloc at 0x%lx not against global symbol "),
                 (unsigned long)r_offset);
      return;

    case elfcpp::R_MIPS_GOT_PAGE:
    case elfcpp::R_MICROMIPS_GOT_PAGE:
    case elfcpp::R_MIPS16_GOT16:
    case elfcpp::R_MIPS_GOT16:
    case elfcpp::R_MIPS_GOT_HI16:
    case elfcpp::R_MIPS_GOT_LO16:
    case elfcpp::R_MICROMIPS_GOT16:
    case elfcpp::R_MICROMIPS_GOT_HI16:
    case elfcpp::R_MICROMIPS_GOT_LO16:
      {
        // This relocation needs a page entry in the GOT.
        // Get the section contents.
        section_size_type view_size = 0;
        const unsigned char* view = object->section_contents(data_shndx,
                                                             &view_size, false);
        view += r_offset;

        Valtype32 val = elfcpp::Swap<32, big_endian>::readval(view);
        Valtype32 addend = (rel_type == elfcpp::SHT_REL ? val & 0xffff
                                                        : r_addend);

        if (rel_type == elfcpp::SHT_REL && got16_reloc(r_type))
          target->got16_addends_.push_back(got16_addend<size, big_endian>(
              object, data_shndx, r_type, r_sym, addend));
        else
          target->got_section()->record_got_page_entry(mips_obj, r_sym, addend);
        break;
      }

    case elfcpp::R_MIPS_HI16:
    case elfcpp::R_MIPS_PCHI16:
    case elfcpp::R_MIPS16_HI16:
    case elfcpp::R_MICROMIPS_HI16:
      // Record the reloc so that we can check whether the corresponding LO16
      // part exists.
      if (rel_type == elfcpp::SHT_REL)
        target->got16_addends_.push_back(got16_addend<size, big_endian>(
            object, data_shndx, r_type, r_sym, 0));
      break;

    case elfcpp::R_MIPS_LO16:
    case elfcpp::R_MIPS_PCLO16:
    case elfcpp::R_MIPS16_LO16:
    case elfcpp::R_MICROMIPS_LO16:
      {
        if (rel_type != elfcpp::SHT_REL)
          break;

        // Find corresponding GOT16/HI16 relocation.

        // According to the MIPS ELF ABI, the R_MIPS_LO16 relocation must
        // be immediately following.  However, for the IRIX6 ABI, the next
        // relocation may be a composed relocation consisting of several
        // relocations for the same address.  In that case, the R_MIPS_LO16
        // relocation may occur as one of these.  We permit a similar
        // extension in general, as that is useful for GCC.

        // In some cases GCC dead code elimination removes the LO16 but
        // keeps the corresponding HI16.  This is strictly speaking a
        // violation of the ABI but not immediately harmful.

        typename std::list<got16_addend<size, big_endian> >::iterator it =
          target->got16_addends_.begin();
        while (it != target->got16_addends_.end())
          {
            got16_addend<size, big_endian> _got16_addend = *it;

            // TODO(sasa): Split got16_addends_ list into two lists - one for
            // GOT16 relocs and the other for HI16 relocs.

            // Report an error if we find HI16 or GOT16 reloc from the
            // previous section without the matching LO16 part.
            if (_got16_addend.object != object
                || _got16_addend.shndx != data_shndx)
              {
                gold_error("Can't find matching LO16 reloc");
                break;
              }

            if (_got16_addend.r_sym != r_sym
                || !is_matching_lo16_reloc(_got16_addend.r_type, r_type))
              {
                ++it;
                continue;
              }

            // We found a matching HI16 or GOT16 reloc for this LO16 reloc.
            // For GOT16, we need to calculate combined addend and record GOT page
            // entry.
            if (got16_reloc(_got16_addend.r_type))
              {

                section_size_type view_size = 0;
                const unsigned char* view = object->section_contents(data_shndx,
                                                                     &view_size,
                                                                     false);
                view += r_offset;

                Valtype32 val = elfcpp::Swap<32, big_endian>::readval(view);
                int32_t addend = Bits<16>::sign_extend32(val & 0xffff);

                addend = (_got16_addend.addend << 16) + addend;
                target->got_section()->record_got_page_entry(mips_obj, r_sym,
                                                             addend);
              }

            it = target->got16_addends_.erase(it);
          }
        break;
      }
    }

  switch (r_type)
    {
    case elfcpp::R_MIPS_32:
    case elfcpp::R_MIPS_REL32:
    case elfcpp::R_MIPS_64:
      {
        if (parameters->options().output_is_position_independent())
          {
            // If building a shared library (or a position-independent
            // executable), we need to create a dynamic relocation for
            // this location.
            if (is_readonly_section(output_section))
              break;
            Reloc_section* rel_dyn = target->rel_dyn_section(layout);
            rel_dyn->add_symbolless_local_addend(object, r_sym,
                                                 elfcpp::R_MIPS_REL32,
                                                 output_section, data_shndx,
                                                 r_offset);
          }
        break;
      }

    case elfcpp::R_MIPS_TLS_GOTTPREL:
    case elfcpp::R_MIPS16_TLS_GOTTPREL:
    case elfcpp::R_MICROMIPS_TLS_GOTTPREL:
    case elfcpp::R_MIPS_TLS_LDM:
    case elfcpp::R_MIPS16_TLS_LDM:
    case elfcpp::R_MICROMIPS_TLS_LDM:
    case elfcpp::R_MIPS_TLS_GD:
    case elfcpp::R_MIPS16_TLS_GD:
    case elfcpp::R_MICROMIPS_TLS_GD:
      {
        bool output_is_shared = parameters->options().shared();
        const tls::Tls_optimization optimized_type
            = Target_mips<size, big_endian>::optimize_tls_reloc(
                                             !output_is_shared, r_type);
        switch (r_type)
          {
          case elfcpp::R_MIPS_TLS_GD:
          case elfcpp::R_MIPS16_TLS_GD:
          case elfcpp::R_MICROMIPS_TLS_GD:
            if (optimized_type == tls::TLSOPT_NONE)
              {
                // Create a pair of GOT entries for the module index and
                // dtv-relative offset.
                Mips_output_data_got<size, big_endian>* got =
                  target->got_section(symtab, layout);
                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;
                  }
                got->record_local_got_symbol(mips_obj, r_sym, r_addend, r_type,
                                             shndx, false);
              }
            else
              {
                // FIXME: TLS optimization not supported yet.
                gold_unreachable();
              }
            break;

          case elfcpp::R_MIPS_TLS_LDM:
          case elfcpp::R_MIPS16_TLS_LDM:
          case elfcpp::R_MICROMIPS_TLS_LDM:
            if (optimized_type == tls::TLSOPT_NONE)
              {
                // We always record LDM symbols as local with index 0.
                target->got_section()->record_local_got_symbol(mips_obj, 0,
                                                               r_addend, r_type,
                                                               -1U, false);
              }
            else
              {
                // FIXME: TLS optimization not supported yet.
                gold_unreachable();
              }
            break;
          case elfcpp::R_MIPS_TLS_GOTTPREL:
          case elfcpp::R_MIPS16_TLS_GOTTPREL:
          case elfcpp::R_MICROMIPS_TLS_GOTTPREL:
            layout->set_has_static_tls();
            if (optimized_type == tls::TLSOPT_NONE)
              {
                // Create a GOT entry for the tp-relative offset.
                Mips_output_data_got<size, big_endian>* got =
                  target->got_section(symtab, layout);
                got->record_local_got_symbol(mips_obj, r_sym, r_addend, r_type,
                                             -1U, false);
              }
            else
              {
                // FIXME: TLS optimization not supported yet.
                gold_unreachable();
              }
            break;

          default:
            gold_unreachable();
        }
      }
      break;

    default:
      break;
    }

  // Refuse some position-dependent relocations when creating a
  // shared library.  Do not refuse R_MIPS_32 / R_MIPS_64; they're
  // not PIC, but we can create dynamic relocations and the result
  // will be fine.  Also do not refuse R_MIPS_LO16, which can be
  // combined with R_MIPS_GOT16.
  if (parameters->options().shared())
    {
      switch (r_type)
        {
        case elfcpp::R_MIPS16_HI16:
        case elfcpp::R_MIPS_HI16:
        case elfcpp::R_MIPS_HIGHER:
        case elfcpp::R_MIPS_HIGHEST:
        case elfcpp::R_MICROMIPS_HI16:
        case elfcpp::R_MICROMIPS_HIGHER:
        case elfcpp::R_MICROMIPS_HIGHEST:
          // Don't refuse a high part relocation if it's against
          // no symbol (e.g. part of a compound relocation).
          if (r_sym == 0)
            break;
	  // Fall through.

        case elfcpp::R_MIPS16_26:
        case elfcpp::R_MIPS_26:
        case elfcpp::R_MICROMIPS_26_S1:
          gold_error(_("%s: relocation %u against `%s' can not be used when "
                       "making a shared object; recompile with -fPIC"),
                     object->name().c_str(), r_type, "a local symbol");
        default:
          break;
        }
    }
}

template<int size, bool big_endian>
inline void
Target_mips<size, big_endian>::Scan::local(
                        Symbol_table* symtab,
                        Layout* layout,
                        Target_mips<size, big_endian>* target,
                        Sized_relobj_file<size, big_endian>* object,
                        unsigned int data_shndx,
                        Output_section* output_section,
                        const Reltype& reloc,
                        unsigned int r_type,
                        const elfcpp::Sym<size, big_endian>& lsym,
                        bool is_discarded)
{
  if (is_discarded)
    return;

  local(
    symtab,
    layout,
    target,
    object,
    data_shndx,
    output_section,
    (const Relatype*) NULL,
    &reloc,
    elfcpp::SHT_REL,
    r_type,
    lsym, is_discarded);
}


template<int size, bool big_endian>
inline void
Target_mips<size, big_endian>::Scan::local(
                        Symbol_table* symtab,
                        Layout* layout,
                        Target_mips<size, big_endian>* target,
                        Sized_relobj_file<size, big_endian>* object,
                        unsigned int data_shndx,
                        Output_section* output_section,
                        const Relatype& reloc,
                        unsigned int r_type,
                        const elfcpp::Sym<size, big_endian>& lsym,
                        bool is_discarded)
{
  if (is_discarded)
    return;

  local(
    symtab,
    layout,
    target,
    object,
    data_shndx,
    output_section,
    &reloc,
    (const Reltype*) NULL,
    elfcpp::SHT_RELA,
    r_type,
    lsym, is_discarded);
}

// Scan a relocation for a global symbol.

template<int size, bool big_endian>
inline void
Target_mips<size, big_endian>::Scan::global(
                                Symbol_table* symtab,
                                Layout* layout,
                                Target_mips<size, big_endian>* target,
                                Sized_relobj_file<size, big_endian>* object,
                                unsigned int data_shndx,
                                Output_section* output_section,
                                const Relatype* rela,
                                const Reltype* rel,
                                unsigned int rel_type,
                                unsigned int r_type,
                                Symbol* gsym)
{
  Mips_address r_offset;
  unsigned int r_sym;
  typename elfcpp::Elf_types<size>::Elf_Swxword r_addend;

  if (rel_type == elfcpp::SHT_RELA)
    {
      r_offset = rela->get_r_offset();
      r_sym = Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>::
	  get_r_sym(rela);
      r_addend = rela->get_r_addend();
    }
  else
    {
      r_offset = rel->get_r_offset();
      r_sym = Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>::
	  get_r_sym(rel);
      r_addend = 0;
    }

  Mips_relobj<size, big_endian>* mips_obj =
    Mips_relobj<size, big_endian>::as_mips_relobj(object);
  Mips_symbol<size>* mips_sym = Mips_symbol<size>::as_mips_sym(gsym);

  if (mips_obj->is_mips16_stub_section(data_shndx))
    {
      mips_obj->get_mips16_stub_section(data_shndx)
              ->new_global_reloc_found(r_type, mips_sym);
    }

  if (r_type == elfcpp::R_MIPS_NONE)
    // R_MIPS_NONE is used in mips16 stub sections, to define the target of the
    // mips16 stub.
    return;

  if (!mips16_call_reloc(r_type)
      && !mips_obj->section_allows_mips16_refs(data_shndx))
    // This reloc would need to refer to a MIPS16 hard-float stub, if
    // there is one.  We ignore MIPS16 stub sections and .pdr section when
    // looking for relocs that would need to refer to MIPS16 stubs.
    mips_sym->set_need_fn_stub();

  // We need PLT entries if there are static-only relocations against
  // an externally-defined function.  This can technically occur for
  // shared libraries if there are branches to the symbol, although it
  // is unlikely that this will be used in practice due to the short
  // ranges involved.  It can occur for any relative or absolute relocation
  // in executables; in that case, the PLT entry becomes the function's
  // canonical address.
  bool static_reloc = false;

  // Set CAN_MAKE_DYNAMIC to true if we can convert this
  // relocation into a dynamic one.
  bool can_make_dynamic = false;
  switch (r_type)
    {
    case elfcpp::R_MIPS_GOT16:
    case elfcpp::R_MIPS_CALL16:
    case elfcpp::R_MIPS_CALL_HI16:
    case elfcpp::R_MIPS_CALL_LO16:
    case elfcpp::R_MIPS_GOT_HI16:
    case elfcpp::R_MIPS_GOT_LO16:
    case elfcpp::R_MIPS_GOT_PAGE:
    case elfcpp::R_MIPS_GOT_OFST:
    case elfcpp::R_MIPS_GOT_DISP:
    case elfcpp::R_MIPS_TLS_GOTTPREL:
    case elfcpp::R_MIPS_TLS_GD:
    case elfcpp::R_MIPS_TLS_LDM:
    case elfcpp::R_MIPS16_GOT16:
    case elfcpp::R_MIPS16_CALL16:
    case elfcpp::R_MIPS16_TLS_GOTTPREL:
    case elfcpp::R_MIPS16_TLS_GD:
    case elfcpp::R_MIPS16_TLS_LDM:
    case elfcpp::R_MICROMIPS_GOT16:
    case elfcpp::R_MICROMIPS_CALL16:
    case elfcpp::R_MICROMIPS_CALL_HI16:
    case elfcpp::R_MICROMIPS_CALL_LO16:
    case elfcpp::R_MICROMIPS_GOT_HI16:
    case elfcpp::R_MICROMIPS_GOT_LO16:
    case elfcpp::R_MICROMIPS_GOT_PAGE:
    case elfcpp::R_MICROMIPS_GOT_OFST:
    case elfcpp::R_MICROMIPS_GOT_DISP:
    case elfcpp::R_MICROMIPS_TLS_GOTTPREL:
    case elfcpp::R_MICROMIPS_TLS_GD:
    case elfcpp::R_MICROMIPS_TLS_LDM:
    case elfcpp::R_MIPS_EH:
      // We need a GOT section.
      target->got_section(symtab, layout);
      break;

    // This is just a hint; it can safely be ignored.  Don't set
    // has_static_relocs for the corresponding symbol.
    case elfcpp::R_MIPS_JALR:
    case elfcpp::R_MICROMIPS_JALR:
      break;

    case elfcpp::R_MIPS_GPREL16:
    case elfcpp::R_MIPS_GPREL32:
    case elfcpp::R_MIPS16_GPREL:
    case elfcpp::R_MICROMIPS_GPREL16:
      // TODO(sasa)
      // GP-relative relocations always resolve to a definition in a
      // regular input file, ignoring the one-definition rule.  This is
      // important for the GP setup sequence in NewABI code, which
      // always resolves to a local function even if other relocations
      // against the symbol wouldn't.
      //constrain_symbol_p = FALSE;
      break;

    case elfcpp::R_MIPS_32:
    case elfcpp::R_MIPS_REL32:
    case elfcpp::R_MIPS_64:
      if ((parameters->options().shared()
          || (strcmp(gsym->name(), "__gnu_local_gp") != 0
          && (!is_readonly_section(output_section)
          || mips_obj->is_pic())))
          && (output_section->flags() & elfcpp::SHF_ALLOC) != 0)
        {
          if (r_type != elfcpp::R_MIPS_REL32)
            mips_sym->set_pointer_equality_needed();
          can_make_dynamic = true;
          break;
        }
      // Fall through.

    default:
      // Most static relocations require pointer equality, except
      // for branches.
      mips_sym->set_pointer_equality_needed();
      // Fall through.

    case elfcpp::R_MIPS_26:
    case elfcpp::R_MIPS_PC16:
    case elfcpp::R_MIPS_PC21_S2:
    case elfcpp::R_MIPS_PC26_S2:
    case elfcpp::R_MIPS16_26:
    case elfcpp::R_MICROMIPS_26_S1:
    case elfcpp::R_MICROMIPS_PC7_S1:
    case elfcpp::R_MICROMIPS_PC10_S1:
    case elfcpp::R_MICROMIPS_PC16_S1:
    case elfcpp::R_MICROMIPS_PC23_S2:
      static_reloc = true;
      mips_sym->set_has_static_relocs();
      break;
    }

  // If there are call relocations against an externally-defined symbol,
  // see whether we can create a MIPS lazy-binding stub for it.  We can
  // only do this if all references to the function are through call
  // relocations, and in that case, the traditional lazy-binding stubs
  // are much more efficient than PLT entries.
  switch (r_type)
    {
    case elfcpp::R_MIPS16_CALL16:
    case elfcpp::R_MIPS_CALL16:
    case elfcpp::R_MIPS_CALL_HI16:
    case elfcpp::R_MIPS_CALL_LO16:
    case elfcpp::R_MIPS_JALR:
    case elfcpp::R_MICROMIPS_CALL16:
    case elfcpp::R_MICROMIPS_CALL_HI16:
    case elfcpp::R_MICROMIPS_CALL_LO16:
    case elfcpp::R_MICROMIPS_JALR:
      if (!mips_sym->no_lazy_stub())
        {
          if ((mips_sym->needs_plt_entry() && mips_sym->is_from_dynobj())
              // Calls from shared objects to undefined symbols of type
              // STT_NOTYPE need lazy-binding stub.
              || (mips_sym->is_undefined() && parameters->options().shared()))
            target->mips_stubs_section(layout)->make_entry(mips_sym);
        }
      break;
    default:
      {
        // We must not create a stub for a symbol that has relocations
        // related to taking the function's address.
        mips_sym->set_no_lazy_stub();
        target->remove_lazy_stub_entry(mips_sym);
        break;
      }
  }

  if (relocation_needs_la25_stub<size, big_endian>(mips_obj, r_type,
                                                   mips_sym->is_mips16()))
    mips_sym->set_has_nonpic_branches();

  // R_MIPS_HI16 against _gp_disp is used for $gp setup,
  // and has a special meaning.
  bool gp_disp_against_hi16 = (!mips_obj->is_newabi()
                               && strcmp(gsym->name(), "_gp_disp") == 0
                               && (hi16_reloc(r_type) || lo16_reloc(r_type)));
  if (static_reloc && gsym->needs_plt_entry())
    {
      target->make_plt_entry(symtab, layout, mips_sym, r_type);

      // 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();
          // We distinguish between PLT entries and lazy-binding stubs by
          // giving the former an st_other value of STO_MIPS_PLT.  Set the
          // flag if there are any relocations in the binary where pointer
          // equality matters.
          if (mips_sym->pointer_equality_needed())
            mips_sym->set_mips_plt();
        }
    }
  if ((static_reloc || can_make_dynamic) && !gp_disp_against_hi16)
    {
      // Absolute addressing relocations.
      // 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, r_type, r_offset);
            }
          else if (can_make_dynamic)
            {
              // Create .rel.dyn section.
              target->rel_dyn_section(layout);
              target->dynamic_reloc(mips_sym, elfcpp::R_MIPS_REL32, mips_obj,
                                    data_shndx, output_section, r_offset);
            }
          else
            gold_error(_("non-dynamic relocations refer to dynamic symbol %s"),
                       gsym->name());
        }
    }

  bool for_call = false;
  switch (r_type)
    {
    case elfcpp::R_MIPS_CALL16:
    case elfcpp::R_MIPS16_CALL16:
    case elfcpp::R_MICROMIPS_CALL16:
    case elfcpp::R_MIPS_CALL_HI16:
    case elfcpp::R_MIPS_CALL_LO16:
    case elfcpp::R_MICROMIPS_CALL_HI16:
    case elfcpp::R_MICROMIPS_CALL_LO16:
      for_call = true;
      // Fall through.

    case elfcpp::R_MIPS16_GOT16:
    case elfcpp::R_MIPS_GOT16:
    case elfcpp::R_MIPS_GOT_HI16:
    case elfcpp::R_MIPS_GOT_LO16:
    case elfcpp::R_MICROMIPS_GOT16:
    case elfcpp::R_MICROMIPS_GOT_HI16:
    case elfcpp::R_MICROMIPS_GOT_LO16:
    case elfcpp::R_MIPS_GOT_DISP:
    case elfcpp::R_MICROMIPS_GOT_DISP:
    case elfcpp::R_MIPS_EH:
      {
        // The symbol requires a GOT entry.
        Mips_output_data_got<size, big_endian>* got =
          target->got_section(symtab, layout);
        got->record_global_got_symbol(mips_sym, mips_obj, r_type, false,
                                      for_call);
        mips_sym->set_global_got_area(GGA_NORMAL);
      }
      break;

    case elfcpp::R_MIPS_GOT_PAGE:
    case elfcpp::R_MICROMIPS_GOT_PAGE:
      {
        // This relocation needs a page entry in the GOT.
        // Get the section contents.
        section_size_type view_size = 0;
        const unsigned char* view =
          object->section_contents(data_shndx, &view_size, false);
        view += r_offset;

        Valtype32 val = elfcpp::Swap<32, big_endian>::readval(view);
        Valtype32 addend = (rel_type == elfcpp::SHT_REL ? val & 0xffff
                                                        : r_addend);
        Mips_output_data_got<size, big_endian>* got =
          target->got_section(symtab, layout);
        got->record_got_page_entry(mips_obj, r_sym, addend);

        // If this is a global, overridable symbol, GOT_PAGE will
        // decay to GOT_DISP, so we'll need a GOT entry for it.
        bool def_regular = (mips_sym->source() == Symbol::FROM_OBJECT
                            && !mips_sym->object()->is_dynamic()
                            && !mips_sym->is_undefined());
        if (!def_regular
            || (parameters->options().output_is_position_independent()
                && !parameters->options().Bsymbolic()
                && !mips_sym->is_forced_local()))
          {
            got->record_global_got_symbol(mips_sym, mips_obj, r_type, false,
                                          for_call);
            mips_sym->set_global_got_area(GGA_NORMAL);
          }
      }
      break;

    case elfcpp::R_MIPS_TLS_GOTTPREL:
    case elfcpp::R_MIPS16_TLS_GOTTPREL:
    case elfcpp::R_MICROMIPS_TLS_GOTTPREL:
    case elfcpp::R_MIPS_TLS_LDM:
    case elfcpp::R_MIPS16_TLS_LDM:
    case elfcpp::R_MICROMIPS_TLS_LDM:
    case elfcpp::R_MIPS_TLS_GD:
    case elfcpp::R_MIPS16_TLS_GD:
    case elfcpp::R_MICROMIPS_TLS_GD:
      {
        const bool is_final = gsym->final_value_is_known();
        const tls::Tls_optimization optimized_type =
          Target_mips<size, big_endian>::optimize_tls_reloc(is_final, r_type);

        switch (r_type)
          {
          case elfcpp::R_MIPS_TLS_GD:
          case elfcpp::R_MIPS16_TLS_GD:
          case elfcpp::R_MICROMIPS_TLS_GD:
            if (optimized_type == tls::TLSOPT_NONE)
              {
                // Create a pair of GOT entries for the module index and
                // dtv-relative offset.
                Mips_output_data_got<size, big_endian>* got =
                  target->got_section(symtab, layout);
                got->record_global_got_symbol(mips_sym, mips_obj, r_type, false,
                                              false);
              }
            else
              {
                // FIXME: TLS optimization not supported yet.
                gold_unreachable();
              }
            break;

          case elfcpp::R_MIPS_TLS_LDM:
          case elfcpp::R_MIPS16_TLS_LDM:
          case elfcpp::R_MICROMIPS_TLS_LDM:
            if (optimized_type == tls::TLSOPT_NONE)
              {
                // We always record LDM symbols as local with index 0.
                target->got_section()->record_local_got_symbol(mips_obj, 0,
                                                               r_addend, r_type,
                                                               -1U, false);
              }
            else
              {
                // FIXME: TLS optimization not supported yet.
                gold_unreachable();
              }
            break;
          case elfcpp::R_MIPS_TLS_GOTTPREL:
          case elfcpp::R_MIPS16_TLS_GOTTPREL:
          case elfcpp::R_MICROMIPS_TLS_GOTTPREL:
            layout->set_has_static_tls();
            if (optimized_type == tls::TLSOPT_NONE)
              {
                // Create a GOT entry for the tp-relative offset.
                Mips_output_data_got<size, big_endian>* got =
                  target->got_section(symtab, layout);
                got->record_global_got_symbol(mips_sym, mips_obj, r_type, false,
                                              false);
              }
            else
              {
                // FIXME: TLS optimization not supported yet.
                gold_unreachable();
              }
            break;

          default:
            gold_unreachable();
        }
      }
      break;
    case elfcpp::R_MIPS_COPY:
    case elfcpp::R_MIPS_JUMP_SLOT:
      // 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;

    default:
      break;
    }

  // Refuse some position-dependent relocations when creating a
  // shared library.  Do not refuse R_MIPS_32 / R_MIPS_64; they're
  // not PIC, but we can create dynamic relocations and the result
  // will be fine.  Also do not refuse R_MIPS_LO16, which can be
  // combined with R_MIPS_GOT16.
  if (parameters->options().shared())
    {
      switch (r_type)
        {
        case elfcpp::R_MIPS16_HI16:
        case elfcpp::R_MIPS_HI16:
        case elfcpp::R_MIPS_HIGHER:
        case elfcpp::R_MIPS_HIGHEST:
        case elfcpp::R_MICROMIPS_HI16:
        case elfcpp::R_MICROMIPS_HIGHER:
        case elfcpp::R_MICROMIPS_HIGHEST:
          // Don't refuse a high part relocation if it's against
          // no symbol (e.g. part of a compound relocation).
          if (r_sym == 0)
            break;

          // R_MIPS_HI16 against _gp_disp is used for $gp setup,
          // and has a special meaning.
          if (!mips_obj->is_newabi() && strcmp(gsym->name(), "_gp_disp") == 0)
            break;
	  // Fall through.

        case elfcpp::R_MIPS16_26:
        case elfcpp::R_MIPS_26:
        case elfcpp::R_MICROMIPS_26_S1:
          gold_error(_("%s: relocation %u against `%s' can not be used when "
                       "making a shared object; recompile with -fPIC"),
                     object->name().c_str(), r_type, gsym->name());
        default:
          break;
        }
    }
}

template<int size, bool big_endian>
inline void
Target_mips<size, big_endian>::Scan::global(
                                Symbol_table* symtab,
                                Layout* layout,
                                Target_mips<size, big_endian>* target,
                                Sized_relobj_file<size, big_endian>* object,
                                unsigned int data_shndx,
                                Output_section* output_section,
                                const Relatype& reloc,
                                unsigned int r_type,
                                Symbol* gsym)
{
  global(
    symtab,
    layout,
    target,
    object,
    data_shndx,
    output_section,
    &reloc,
    (const Reltype*) NULL,
    elfcpp::SHT_RELA,
    r_type,
    gsym);
}

template<int size, bool big_endian>
inline void
Target_mips<size, big_endian>::Scan::global(
                                Symbol_table* symtab,
                                Layout* layout,
                                Target_mips<size, big_endian>* target,
                                Sized_relobj_file<size, big_endian>* object,
                                unsigned int data_shndx,
                                Output_section* output_section,
                                const Reltype& reloc,
                                unsigned int r_type,
                                Symbol* gsym)
{
  global(
    symtab,
    layout,
    target,
    object,
    data_shndx,
    output_section,
    (const Relatype*) NULL,
    &reloc,
    elfcpp::SHT_REL,
    r_type,
    gsym);
}

// Return whether a R_MIPS_32/R_MIPS64 relocation needs to be applied.
// In cases where Scan::local() or Scan::global() has created
// a dynamic relocation, the addend of the relocation is carried
// in the data, and we must not apply the static relocation.

template<int size, bool big_endian>
inline bool
Target_mips<size, big_endian>::Relocate::should_apply_static_reloc(
    const Mips_symbol<size>* gsym,
    unsigned int r_type,
    Output_section* output_section,
    Target_mips* target)
{
  // 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;

  if (gsym == NULL)
    return true;
  else
    {
      // For global symbols, we use the same helper routines used in the
      // scan pass.
      if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))
          && !gsym->may_need_copy_reloc())
        {
          // We have generated dynamic reloc (R_MIPS_REL32).

          bool multi_got = false;
          if (target->has_got_section())
            multi_got = target->got_section()->multi_got();
          bool has_got_offset;
          if (!multi_got)
            has_got_offset = gsym->has_got_offset(GOT_TYPE_STANDARD);
          else
            has_got_offset = gsym->global_gotoffset() != -1U;
          if (!has_got_offset)
            return true;
          else
            // Apply the relocation only if the symbol is in the local got.
            // Do not apply the relocation if the symbol is in the global
            // got.
            return symbol_references_local(gsym, gsym->has_dynsym_index());
        }
      else
        // We have not generated dynamic reloc.
        return true;
    }
}

// Perform a relocation.

template<int size, bool big_endian>
inline bool
Target_mips<size, big_endian>::Relocate::relocate(
                        const Relocate_info<size, big_endian>* relinfo,
                        unsigned int rel_type,
                        Target_mips* target,
                        Output_section* output_section,
                        size_t relnum,
                        const unsigned char* preloc,
                        const Sized_symbol<size>* gsym,
                        const Symbol_value<size>* psymval,
                        unsigned char* view,
                        Mips_address address,
                        section_size_type)
{
  Mips_address r_offset;
  unsigned int r_sym;
  unsigned int r_type;
  unsigned int r_type2;
  unsigned int r_type3;
  unsigned char r_ssym;
  typename elfcpp::Elf_types<size>::Elf_Swxword r_addend;
  // r_offset and r_type of the next relocation is needed for resolving multiple
  // consecutive relocations with the same offset.
  Mips_address next_r_offset = static_cast<Mips_address>(0) - 1;
  unsigned int next_r_type = elfcpp::R_MIPS_NONE;

  elfcpp::Shdr<size, big_endian> shdr(relinfo->reloc_shdr);
  size_t reloc_count = shdr.get_sh_size() / shdr.get_sh_entsize();

  if (rel_type == elfcpp::SHT_RELA)
    {
      const Relatype rela(preloc);
      r_offset = rela.get_r_offset();
      r_sym = Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>::
	  get_r_sym(&rela);
      r_type = Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>::
	  get_r_type(&rela);
      r_type2 = Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>::
          get_r_type2(&rela);
      r_type3 = Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>::
          get_r_type3(&rela);
      r_ssym = Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>::
          get_r_ssym(&rela);
      r_addend = rela.get_r_addend();
      // If this is not last relocation, get r_offset and r_type of the next
      // relocation.
      if (relnum + 1 < reloc_count)
        {
          const int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
          const Relatype next_rela(preloc + reloc_size);
          next_r_offset = next_rela.get_r_offset();
          next_r_type =
            Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>::
              get_r_type(&next_rela);
        }
    }
  else
    {
      const Reltype rel(preloc);
      r_offset = rel.get_r_offset();
      r_sym = Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>::
	  get_r_sym(&rel);
      r_type = Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>::
	  get_r_type(&rel);
      r_ssym = 0;
      r_type2 = elfcpp::R_MIPS_NONE;
      r_type3 = elfcpp::R_MIPS_NONE;
      r_addend = 0;
      // If this is not last relocation, get r_offset and r_type of the next
      // relocation.
      if (relnum + 1 < reloc_count)
        {
          const int reloc_size = elfcpp::Elf_sizes<size>::rel_size;
          const Reltype next_rel(preloc + reloc_size);
          next_r_offset = next_rel.get_r_offset();
          next_r_type = Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>::
            get_r_type(&next_rel);
        }
    }

  typedef Mips_relocate_functions<size, big_endian> Reloc_funcs;
  typename Reloc_funcs::Status reloc_status = Reloc_funcs::STATUS_OKAY;

  Mips_relobj<size, big_endian>* object =
      Mips_relobj<size, big_endian>::as_mips_relobj(relinfo->object);

  bool target_is_16_bit_code = false;
  bool target_is_micromips_code = false;
  bool cross_mode_jump;

  Symbol_value<size> symval;

  const Mips_symbol<size>* mips_sym = Mips_symbol<size>::as_mips_sym(gsym);

  bool changed_symbol_value = false;
  if (gsym == NULL)
    {
      target_is_16_bit_code = object->local_symbol_is_mips16(r_sym);
      target_is_micromips_code = object->local_symbol_is_micromips(r_sym);
      if (target_is_16_bit_code || target_is_micromips_code)
        {
          // MIPS16/microMIPS text labels should be treated as odd.
          symval.set_output_value(psymval->value(object, 1));
          psymval = &symval;
          changed_symbol_value = true;
        }
    }
  else
    {
      target_is_16_bit_code = mips_sym->is_mips16();
      target_is_micromips_code = mips_sym->is_micromips();

      // If this is a mips16/microMIPS text symbol, add 1 to the value to make
      // it odd.  This will cause something like .word SYM to come up with
      // the right value when it is loaded into the PC.

      if ((mips_sym->is_mips16() || mips_sym->is_micromips())
          && psymval->value(object, 0) != 0)
        {
          symval.set_output_value(psymval->value(object, 0) | 1);
          psymval = &symval;
          changed_symbol_value = true;
        }

      // Pick the value to use for symbols defined in shared objects.
      if (mips_sym->use_plt_offset(Scan::get_reference_flags(r_type))
          || mips_sym->has_lazy_stub())
        {
          Mips_address value;
          if (!mips_sym->has_lazy_stub())
            {
              // Prefer a standard MIPS PLT entry.
              if (mips_sym->has_mips_plt_offset())
                {
                  value = target->plt_section()->mips_entry_address(mips_sym);
                  target_is_micromips_code = false;
                  target_is_16_bit_code = false;
                }
              else
                {
                  value = (target->plt_section()->comp_entry_address(mips_sym)
                           + 1);
                  if (target->is_output_micromips())
                    target_is_micromips_code = true;
                  else
                    target_is_16_bit_code = true;
                }
            }
          else
            value = target->mips_stubs_section()->stub_address(mips_sym);

          symval.set_output_value(value);
          psymval = &symval;
        }
    }

  // TRUE if the symbol referred to by this relocation is "_gp_disp".
  // Note that such a symbol must always be a global symbol.
  bool gp_disp = (gsym != NULL && (strcmp(gsym->name(), "_gp_disp") == 0)
                  && !object->is_newabi());

  // TRUE if the symbol referred to by this relocation is "__gnu_local_gp".
  // Note that such a symbol must always be a global symbol.
  bool gnu_local_gp = gsym && (strcmp(gsym->name(), "__gnu_local_gp") == 0);


  if (gp_disp)
    {
      if (!hi16_reloc(r_type) && !lo16_reloc(r_type))
        gold_error_at_location(relinfo, relnum, r_offset,
          _("relocations against _gp_disp are permitted only"
            " with R_MIPS_HI16 and R_MIPS_LO16 relocations."));
    }
  else if (gnu_local_gp)
    {
      // __gnu_local_gp is _gp symbol.
      symval.set_output_value(target->adjusted_gp_value(object));
      psymval = &symval;
    }

  // If this is a reference to a 16-bit function with a stub, we need
  // to redirect the relocation to the stub unless:
  //
  // (a) the relocation is for a MIPS16 JAL;
  //
  // (b) the relocation is for a MIPS16 PIC call, and there are no
  //     non-MIPS16 uses of the GOT slot; or
  //
  // (c) the section allows direct references to MIPS16 functions.
  if (r_type != elfcpp::R_MIPS16_26
      && ((mips_sym != NULL
           && mips_sym->has_mips16_fn_stub()
           && (r_type != elfcpp::R_MIPS16_CALL16 || mips_sym->need_fn_stub()))
          || (mips_sym == NULL
              && object->get_local_mips16_fn_stub(r_sym) != NULL))
      && !object->section_allows_mips16_refs(relinfo->data_shndx))
    {
      // This is a 32- or 64-bit call to a 16-bit function.  We should
      // have already noticed that we were going to need the
      // stub.
      Mips_address value;
      if (mips_sym == NULL)
        value = object->get_local_mips16_fn_stub(r_sym)->output_address();
      else
        {
          gold_assert(mips_sym->need_fn_stub());
          if (mips_sym->has_la25_stub())
            value = target->la25_stub_section()->stub_address(mips_sym);
          else
            {
              value = mips_sym->template
                      get_mips16_fn_stub<big_endian>()->output_address();
            }
          }
      symval.set_output_value(value);
      psymval = &symval;
      changed_symbol_value = true;

      // The target is 16-bit, but the stub isn't.
      target_is_16_bit_code = false;
    }
  // If this is a MIPS16 call with a stub, that is made through the PLT or
  // to a standard MIPS function, we need to redirect the call to the stub.
  // Note that we specifically exclude R_MIPS16_CALL16 from this behavior;
  // indirect calls should use an indirect stub instead.
  else if (r_type == elfcpp::R_MIPS16_26
           && ((mips_sym != NULL
                && (mips_sym->has_mips16_call_stub()
                    || mips_sym->has_mips16_call_fp_stub()))
               || (mips_sym == NULL
                   && object->get_local_mips16_call_stub(r_sym) != NULL))
           && ((mips_sym != NULL && mips_sym->has_plt_offset())
               || !target_is_16_bit_code))
    {
      Mips16_stub_section<size, big_endian>* call_stub;
      if (mips_sym == NULL)
        call_stub = object->get_local_mips16_call_stub(r_sym);
      else
        {
          // If both call_stub and call_fp_stub are defined, we can figure
          // out which one to use by checking which one appears in the input
          // file.
          if (mips_sym->has_mips16_call_stub()
              && mips_sym->has_mips16_call_fp_stub())
            {
              call_stub = NULL;
              for (unsigned int i = 1; i < object->shnum(); ++i)
                {
                  if (object->is_mips16_call_fp_stub_section(i))
                    {
                      call_stub = mips_sym->template
                                  get_mips16_call_fp_stub<big_endian>();
                      break;
                    }

                }
              if (call_stub == NULL)
                call_stub =
                  mips_sym->template get_mips16_call_stub<big_endian>();
            }
          else if (mips_sym->has_mips16_call_stub())
            call_stub = mips_sym->template get_mips16_call_stub<big_endian>();
          else
            call_stub = mips_sym->template get_mips16_call_fp_stub<big_endian>();
        }

      symval.set_output_value(call_stub->output_address());
      psymval = &symval;
      changed_symbol_value = true;
    }
  // If this is a direct call to a PIC function, redirect to the
  // non-PIC stub.
  else if (mips_sym != NULL
           && mips_sym->has_la25_stub()
           && relocation_needs_la25_stub<size, big_endian>(
                                       object, r_type, target_is_16_bit_code))
    {
      Mips_address value = target->la25_stub_section()->stub_address(mips_sym);
      if (mips_sym->is_micromips())
        value += 1;
      symval.set_output_value(value);
      psymval = &symval;
    }
  // For direct MIPS16 and microMIPS calls make sure the compressed PLT
  // entry is used if a standard PLT entry has also been made.
  else if ((r_type == elfcpp::R_MIPS16_26
            || r_type == elfcpp::R_MICROMIPS_26_S1)
          && mips_sym != NULL
          && mips_sym->has_plt_offset()
          && mips_sym->has_comp_plt_offset()
          && mips_sym->has_mips_plt_offset())
    {
      Mips_address value = (target->plt_section()->comp_entry_address(mips_sym)
                            + 1);
      symval.set_output_value(value);
      psymval = &symval;

      target_is_16_bit_code = !target->is_output_micromips();
      target_is_micromips_code = target->is_output_micromips();
    }

  // Make sure MIPS16 and microMIPS are not used together.
  if ((r_type == elfcpp::R_MIPS16_26 && target_is_micromips_code)
      || (micromips_branch_reloc(r_type) && target_is_16_bit_code))
   {
      gold_error(_("MIPS16 and microMIPS functions cannot call each other"));
   }

  // Calls from 16-bit code to 32-bit code and vice versa require the
  // mode change.  However, we can ignore calls to undefined weak symbols,
  // which should never be executed at runtime.  This exception is important
  // because the assembly writer may have "known" that any definition of the
  // symbol would be 16-bit code, and that direct jumps were therefore
  // acceptable.
  cross_mode_jump =
    (!(gsym != NULL && gsym->is_weak_undefined())
     && ((r_type == elfcpp::R_MIPS16_26 && !target_is_16_bit_code)
         || (r_type == elfcpp::R_MICROMIPS_26_S1 && !target_is_micromips_code)
         || ((r_type == elfcpp::R_MIPS_26 || r_type == elfcpp::R_MIPS_JALR)
             && (target_is_16_bit_code || target_is_micromips_code))));

  bool local = (mips_sym == NULL
                || (mips_sym->got_only_for_calls()
                    ? symbol_calls_local(mips_sym, mips_sym->has_dynsym_index())
                    : symbol_references_local(mips_sym,
                                              mips_sym->has_dynsym_index())));

  // Global R_MIPS_GOT_PAGE/R_MICROMIPS_GOT_PAGE relocations are equivalent
  // to R_MIPS_GOT_DISP/R_MICROMIPS_GOT_DISP.  The addend is applied by the
  // corresponding R_MIPS_GOT_OFST/R_MICROMIPS_GOT_OFST.
  if (got_page_reloc(r_type) && !local)
    r_type = (micromips_reloc(r_type) ? elfcpp::R_MICROMIPS_GOT_DISP
                                      : elfcpp::R_MIPS_GOT_DISP);

  unsigned int got_offset = 0;
  int gp_offset = 0;

  // Whether we have to extract addend from instruction.
  bool extract_addend = rel_type == elfcpp::SHT_REL;
  unsigned int r_types[3] = { r_type, r_type2, r_type3 };

  Reloc_funcs::mips_reloc_unshuffle(view, r_type, false);

  // For Mips64 N64 ABI, there may be up to three operations specified per
  // record, by the fields r_type, r_type2, and r_type3. The first operation
  // takes its addend from the relocation record. Each subsequent operation
  // takes as its addend the result of the previous operation.
  // The first operation in a record which references a symbol uses the symbol
  // implied by r_sym. The next operation in a record which references a symbol
  // uses the special symbol value given by the r_ssym field. A third operation
  // in a record which references a symbol will assume a NULL symbol,
  // i.e. value zero.

  // TODO(Vladimir)
  // Check if a record references to a symbol.
  for (unsigned int i = 0; i < 3; ++i)
    {
      if (r_types[i] == elfcpp::R_MIPS_NONE)
        break;

      // If we didn't apply previous relocation, use its result as addend
      // for current.
      if (this->calculate_only_)
        {
          r_addend = this->calculated_value_;
          extract_addend = false;
        }

      // In the N32 and 64-bit ABIs there may be multiple consecutive
      // relocations for the same offset.  In that case we are
      // supposed to treat the output of each relocation as the addend
      // for the next.  For N64 ABI, we are checking offsets only in a
      // third operation in a record (r_type3).
      this->calculate_only_ =
        (object->is_n64() && i < 2
         ? r_types[i+1] != elfcpp::R_MIPS_NONE
         : (r_offset == next_r_offset) && (next_r_type != elfcpp::R_MIPS_NONE));

      if (object->is_n64())
        {
          if (i == 1)
            {
              // Handle special symbol for r_type2 relocation type.
              switch (r_ssym)
                {
                case RSS_UNDEF:
                  symval.set_output_value(0);
                  break;
                case RSS_GP:
                  symval.set_output_value(target->gp_value());
                  break;
                case RSS_GP0:
                  symval.set_output_value(object->gp_value());
                  break;
                case RSS_LOC:
                  symval.set_output_value(address);
                  break;
                default:
                  gold_unreachable();
                }
              psymval = &symval;
            }
          else if (i == 2)
           {
            // For r_type3 symbol value is 0.
            symval.set_output_value(0);
           }
        }

      bool update_got_entry = false;
      switch (r_types[i])
        {
        case elfcpp::R_MIPS_NONE:
          break;
        case elfcpp::R_MIPS_16:
          reloc_status = Reloc_funcs::rel16(view, object, psymval, r_addend,
                                            extract_addend,
                                            this->calculate_only_,
                                            &this->calculated_value_);
          break;

        case elfcpp::R_MIPS_32:
          if (should_apply_static_reloc(mips_sym, r_types[i], output_section,
                                        target))
            reloc_status = Reloc_funcs::rel32(view, object, psymval, r_addend,
                                              extract_addend,
                                              this->calculate_only_,
                                              &this->calculated_value_);
          if (mips_sym != NULL
              && (mips_sym->is_mips16() || mips_sym->is_micromips())
              && mips_sym->global_got_area() == GGA_RELOC_ONLY)
            {
              // If mips_sym->has_mips16_fn_stub() is false, symbol value is
              // already updated by adding +1.
              if (mips_sym->has_mips16_fn_stub())
                {
                  gold_assert(mips_sym->need_fn_stub());
                  Mips16_stub_section<size, big_endian>* fn_stub =
                    mips_sym->template get_mips16_fn_stub<big_endian>();

                  symval.set_output_value(fn_stub->output_address());
                  psymval = &symval;
                }
              got_offset = mips_sym->global_gotoffset();
              update_got_entry = true;
            }
          break;

        case elfcpp::R_MIPS_64:
          if (should_apply_static_reloc(mips_sym, r_types[i], output_section,
                                        target))
            reloc_status = Reloc_funcs::rel64(view, object, psymval, r_addend,
                                              extract_addend,
                                              this->calculate_only_,
                                              &this->calculated_value_, false);
          else if (target->is_output_n64() && r_addend != 0)
            // Only apply the addend.  The static relocation was RELA, but the
            // dynamic relocation is REL, so we need to apply the addend.
            reloc_status = Reloc_funcs::rel64(view, object, psymval, r_addend,
                                              extract_addend,
                                              this->calculate_only_,
                                              &this->calculated_value_, true);
          break;
        case elfcpp::R_MIPS_REL32:
          gold_unreachable();

        case elfcpp::R_MIPS_PC32:
          reloc_status = Reloc_funcs::relpc32(view, object, psymval, address,
                                              r_addend, extract_addend,
                                              this->calculate_only_,
                                              &this->calculated_value_);
          break;

        case elfcpp::R_MIPS16_26:
          // The calculation for R_MIPS16_26 is just the same as for an
          // R_MIPS_26.  It's only the storage of the relocated field into
          // the output file that's different.  So, we just fall through to the
          // R_MIPS_26 case here.
        case elfcpp::R_MIPS_26:
        case elfcpp::R_MICROMIPS_26_S1:
          reloc_status = Reloc_funcs::rel26(view, object, psymval, address,
              gsym == NULL, r_addend, extract_addend, gsym, cross_mode_jump,
              r_types[i], target->jal_to_bal(), this->calculate_only_,
              &this->calculated_value_);
          break;

        case elfcpp::R_MIPS_HI16:
        case elfcpp::R_MIPS16_HI16:
        case elfcpp::R_MICROMIPS_HI16:
          if (rel_type == elfcpp::SHT_RELA)
            reloc_status = Reloc_funcs::do_relhi16(view, object, psymval,
                                                   r_addend, address,
                                                   gp_disp, r_types[i],
                                                   extract_addend, 0,
                                                   target,
                                                   this->calculate_only_,
                                                   &this->calculated_value_);
          else if (rel_type == elfcpp::SHT_REL)
            reloc_status = Reloc_funcs::relhi16(view, object, psymval, r_addend,
                                                address, gp_disp, r_types[i],
                                                r_sym, extract_addend);
          else
            gold_unreachable();
          break;

        case elfcpp::R_MIPS_LO16:
        case elfcpp::R_MIPS16_LO16:
        case elfcpp::R_MICROMIPS_LO16:
        case elfcpp::R_MICROMIPS_HI0_LO16:
          reloc_status = Reloc_funcs::rello16(target, view, object, psymval,
                                              r_addend, extract_addend, address,
                                              gp_disp, r_types[i], r_sym,
                                              rel_type, this->calculate_only_,
                                              &this->calculated_value_);
          break;

        case elfcpp::R_MIPS_LITERAL:
        case elfcpp::R_MICROMIPS_LITERAL:
          // Because we don't merge literal sections, we can handle this
          // just like R_MIPS_GPREL16.  In the long run, we should merge
          // shared literals, and then we will need to additional work
          // here.

          // Fall through.

        case elfcpp::R_MIPS_GPREL16:
        case elfcpp::R_MIPS16_GPREL:
        case elfcpp::R_MICROMIPS_GPREL7_S2:
        case elfcpp::R_MICROMIPS_GPREL16:
          reloc_status = Reloc_funcs::relgprel(view, object, psymval,
                                             target->adjusted_gp_value(object),
                                             r_addend, extract_addend,
                                             gsym == NULL, r_types[i],
                                             this->calculate_only_,
                                             &this->calculated_value_);
          break;

        case elfcpp::R_MIPS_PC16:
          reloc_status = Reloc_funcs::relpc16(view, object, psymval, address,
                                              r_addend, extract_addend,
                                              this->calculate_only_,
                                              &this->calculated_value_);
          break;

        case elfcpp::R_MIPS_PC21_S2:
          reloc_status = Reloc_funcs::relpc21(view, object, psymval, address,
                                              r_addend, extract_addend,
                                              this->calculate_only_,
                                              &this->calculated_value_);
          break;

        case elfcpp::R_MIPS_PC26_S2:
          reloc_status = Reloc_funcs::relpc26(view, object, psymval, address,
                                              r_addend, extract_addend,
                                              this->calculate_only_,
                                              &this->calculated_value_);
          break;

        case elfcpp::R_MIPS_PC18_S3:
          reloc_status = Reloc_funcs::relpc18(view, object, psymval, address,
                                              r_addend, extract_addend,
                                              this->calculate_only_,
                                              &this->calculated_value_);
          break;

        case elfcpp::R_MIPS_PC19_S2:
          reloc_status = Reloc_funcs::relpc19(view, object, psymval, address,
                                              r_addend, extract_addend,
                                              this->calculate_only_,
                                              &this->calculated_value_);
          break;

        case elfcpp::R_MIPS_PCHI16:
          if (rel_type == elfcpp::SHT_RELA)
            reloc_status = Reloc_funcs::do_relpchi16(view, object, psymval,
                                                     r_addend, address,
                                                     extract_addend, 0,
                                                     this->calculate_only_,
                                                     &this->calculated_value_);
          else if (rel_type == elfcpp::SHT_REL)
            reloc_status = Reloc_funcs::relpchi16(view, object, psymval,
                                                  r_addend, address, r_sym,
                                                  extract_addend);
          else
            gold_unreachable();
          break;

        case elfcpp::R_MIPS_PCLO16:
          reloc_status = Reloc_funcs::relpclo16(view, object, psymval, r_addend,
                                                extract_addend, address, r_sym,
                                                rel_type, this->calculate_only_,
                                                &this->calculated_value_);
          break;
        case elfcpp::R_MICROMIPS_PC7_S1:
          reloc_status = Reloc_funcs::relmicromips_pc7_s1(view, object, psymval,
                                                      address, r_addend,
                                                      extract_addend,
                                                      this->calculate_only_,
                                                      &this->calculated_value_);
          break;
        case elfcpp::R_MICROMIPS_PC10_S1:
          reloc_status = Reloc_funcs::relmicromips_pc10_s1(view, object,
                                                      psymval, address,
                                                      r_addend, extract_addend,
                                                      this->calculate_only_,
                                                      &this->calculated_value_);
          break;
        case elfcpp::R_MICROMIPS_PC16_S1:
          reloc_status = Reloc_funcs::relmicromips_pc16_s1(view, object,
                                                      psymval, address,
                                                      r_addend, extract_addend,
                                                      this->calculate_only_,
                                                      &this->calculated_value_);
          break;
        case elfcpp::R_MIPS_GPREL32:
          reloc_status = Reloc_funcs::relgprel32(view, object, psymval,
                                              target->adjusted_gp_value(object),
                                              r_addend, extract_addend,
                                              this->calculate_only_,
                                              &this->calculated_value_);
          break;
        case elfcpp::R_MIPS_GOT_HI16:
        case elfcpp::R_MIPS_CALL_HI16:
        case elfcpp::R_MICROMIPS_GOT_HI16:
        case elfcpp::R_MICROMIPS_CALL_HI16:
          if (gsym != NULL)
            got_offset = target->got_section()->got_offset(gsym,
                                                           GOT_TYPE_STANDARD,
                                                           object);
          else
            got_offset = target->got_section()->got_offset(r_sym,
                                                           GOT_TYPE_STANDARD,
                                                           object, r_addend);
          gp_offset = target->got_section()->gp_offset(got_offset, object);
          reloc_status = Reloc_funcs::relgot_hi16(view, gp_offset,
                                                  this->calculate_only_,
                                                  &this->calculated_value_);
          update_got_entry = changed_symbol_value;
          break;

        case elfcpp::R_MIPS_GOT_LO16:
        case elfcpp::R_MIPS_CALL_LO16:
        case elfcpp::R_MICROMIPS_GOT_LO16:
        case elfcpp::R_MICROMIPS_CALL_LO16:
          if (gsym != NULL)
            got_offset = target->got_section()->got_offset(gsym,
                                                           GOT_TYPE_STANDARD,
                                                           object);
          else
            got_offset = target->got_section()->got_offset(r_sym,
                                                           GOT_TYPE_STANDARD,
                                                           object, r_addend);
          gp_offset = target->got_section()->gp_offset(got_offset, object);
          reloc_status = Reloc_funcs::relgot_lo16(view, gp_offset,
                                                  this->calculate_only_,
                                                  &this->calculated_value_);
          update_got_entry = changed_symbol_value;
          break;

        case elfcpp::R_MIPS_GOT_DISP:
        case elfcpp::R_MICROMIPS_GOT_DISP:
        case elfcpp::R_MIPS_EH:
          if (gsym != NULL)
            got_offset = target->got_section()->got_offset(gsym,
                                                           GOT_TYPE_STANDARD,
                                                           object);
          else
            got_offset = target->got_section()->got_offset(r_sym,
                                                           GOT_TYPE_STANDARD,
                                                           object, r_addend);
          gp_offset = target->got_section()->gp_offset(got_offset, object);
          if (eh_reloc(r_types[i]))
            reloc_status = Reloc_funcs::releh(view, gp_offset,
                                              this->calculate_only_,
                                              &this->calculated_value_);
          else
            reloc_status = Reloc_funcs::relgot(view, gp_offset,
                                               this->calculate_only_,
                                               &this->calculated_value_);
          break;
        case elfcpp::R_MIPS_CALL16:
        case elfcpp::R_MIPS16_CALL16:
        case elfcpp::R_MICROMIPS_CALL16:
          gold_assert(gsym != NULL);
          got_offset = target->got_section()->got_offset(gsym,
                                                         GOT_TYPE_STANDARD,
                                                         object);
          gp_offset = target->got_section()->gp_offset(got_offset, object);
          reloc_status = Reloc_funcs::relgot(view, gp_offset,
                                             this->calculate_only_,
                                             &this->calculated_value_);
          // TODO(sasa): We should also initialize update_got_entry
          // in other place swhere relgot is called.
          update_got_entry = changed_symbol_value;
          break;

        case elfcpp::R_MIPS_GOT16:
        case elfcpp::R_MIPS16_GOT16:
        case elfcpp::R_MICROMIPS_GOT16:
          if (gsym != NULL)
            {
              got_offset = target->got_section()->got_offset(gsym,
                                                             GOT_TYPE_STANDARD,
                                                             object);
              gp_offset = target->got_section()->gp_offset(got_offset, object);
              reloc_status = Reloc_funcs::relgot(view, gp_offset,
                                                 this->calculate_only_,
                                                 &this->calculated_value_);
            }
          else
            {
              if (rel_type == elfcpp::SHT_RELA)
                reloc_status = Reloc_funcs::do_relgot16_local(view, object,
                                                      psymval, r_addend,
                                                      extract_addend, 0,
                                                      target,
                                                      this->calculate_only_,
                                                      &this->calculated_value_);
              else if (rel_type == elfcpp::SHT_REL)
                reloc_status = Reloc_funcs::relgot16_local(view, object,
                                                           psymval, r_addend,
                                                           extract_addend,
                                                           r_types[i], r_sym);
              else
                gold_unreachable();
            }
          update_got_entry = changed_symbol_value;
          break;

        case elfcpp::R_MIPS_TLS_GD:
        case elfcpp::R_MIPS16_TLS_GD:
        case elfcpp::R_MICROMIPS_TLS_GD:
          if (gsym != NULL)
            got_offset = target->got_section()->got_offset(gsym,
                                                           GOT_TYPE_TLS_PAIR,
                                                           object);
          else
            got_offset = target->got_section()->got_offset(r_sym,
                                                           GOT_TYPE_TLS_PAIR,
                                                           object, r_addend);
          gp_offset = target->got_section()->gp_offset(got_offset, object);
          reloc_status = Reloc_funcs::relgot(view, gp_offset,
                                             this->calculate_only_,
                                             &this->calculated_value_);
          break;

        case elfcpp::R_MIPS_TLS_GOTTPREL:
        case elfcpp::R_MIPS16_TLS_GOTTPREL:
        case elfcpp::R_MICROMIPS_TLS_GOTTPREL:
          if (gsym != NULL)
            got_offset = target->got_section()->got_offset(gsym,
                                                           GOT_TYPE_TLS_OFFSET,
                                                           object);
          else
            got_offset = target->got_section()->got_offset(r_sym,
                                                           GOT_TYPE_TLS_OFFSET,
                                                           object, r_addend);
          gp_offset = target->got_section()->gp_offset(got_offset, object);
          reloc_status = Reloc_funcs::relgot(view, gp_offset,
                                             this->calculate_only_,
                                             &this->calculated_value_);
          break;

        case elfcpp::R_MIPS_TLS_LDM:
        case elfcpp::R_MIPS16_TLS_LDM:
        case elfcpp::R_MICROMIPS_TLS_LDM:
          // Relocate the field with the offset of the GOT entry for
          // the module index.
          got_offset = target->got_section()->tls_ldm_offset(object);
          gp_offset = target->got_section()->gp_offset(got_offset, object);
          reloc_status = Reloc_funcs::relgot(view, gp_offset,
                                             this->calculate_only_,
                                             &this->calculated_value_);
          break;

        case elfcpp::R_MIPS_GOT_PAGE:
        case elfcpp::R_MICROMIPS_GOT_PAGE:
          reloc_status = Reloc_funcs::relgotpage(target, view, object, psymval,
                                                 r_addend, extract_addend,
                                                 this->calculate_only_,
                                                 &this->calculated_value_);
          break;

        case elfcpp::R_MIPS_GOT_OFST:
        case elfcpp::R_MICROMIPS_GOT_OFST:
          reloc_status = Reloc_funcs::relgotofst(target, view, object, psymval,
                                                 r_addend, extract_addend,
                                                 local, this->calculate_only_,
                                                 &this->calculated_value_);
          break;

        case elfcpp::R_MIPS_JALR:
        case elfcpp::R_MICROMIPS_JALR:
          // This relocation is only a hint.  In some cases, we optimize
          // it into a bal instruction.  But we don't try to optimize
          // when the symbol does not resolve locally.
          if (gsym == NULL
              || symbol_calls_local(gsym, gsym->has_dynsym_index()))
            reloc_status = Reloc_funcs::reljalr(view, object, psymval, address,
                                                r_addend, extract_addend,
                                                cross_mode_jump, r_types[i],
                                                target->jalr_to_bal(),
                                                target->jr_to_b(),
                                                this->calculate_only_,
                                                &this->calculated_value_);
          break;

        case elfcpp::R_MIPS_TLS_DTPREL_HI16:
        case elfcpp::R_MIPS16_TLS_DTPREL_HI16:
        case elfcpp::R_MICROMIPS_TLS_DTPREL_HI16:
          reloc_status = Reloc_funcs::tlsrelhi16(view, object, psymval,
                                                 elfcpp::DTP_OFFSET, r_addend,
                                                 extract_addend,
                                                 this->calculate_only_,
                                                 &this->calculated_value_);
          break;
        case elfcpp::R_MIPS_TLS_DTPREL_LO16:
        case elfcpp::R_MIPS16_TLS_DTPREL_LO16:
        case elfcpp::R_MICROMIPS_TLS_DTPREL_LO16:
          reloc_status = Reloc_funcs::tlsrello16(view, object, psymval,
                                                 elfcpp::DTP_OFFSET, r_addend,
                                                 extract_addend,
                                                 this->calculate_only_,
                                                 &this->calculated_value_);
          break;
        case elfcpp::R_MIPS_TLS_DTPREL32:
        case elfcpp::R_MIPS_TLS_DTPREL64:
          reloc_status = Reloc_funcs::tlsrel32(view, object, psymval,
                                               elfcpp::DTP_OFFSET, r_addend,
                                               extract_addend,
                                               this->calculate_only_,
                                               &this->calculated_value_);
          break;
        case elfcpp::R_MIPS_TLS_TPREL_HI16:
        case elfcpp::R_MIPS16_TLS_TPREL_HI16:
        case elfcpp::R_MICROMIPS_TLS_TPREL_HI16:
          reloc_status = Reloc_funcs::tlsrelhi16(view, object, psymval,
                                                 elfcpp::TP_OFFSET, r_addend,
                                                 extract_addend,
                                                 this->calculate_only_,
                                                 &this->calculated_value_);
          break;
        case elfcpp::R_MIPS_TLS_TPREL_LO16:
        case elfcpp::R_MIPS16_TLS_TPREL_LO16:
        case elfcpp::R_MICROMIPS_TLS_TPREL_LO16:
          reloc_status = Reloc_funcs::tlsrello16(view, object, psymval,
                                                 elfcpp::TP_OFFSET, r_addend,
                                                 extract_addend,
                                                 this->calculate_only_,
                                                 &this->calculated_value_);
          break;
        case elfcpp::R_MIPS_TLS_TPREL32:
        case elfcpp::R_MIPS_TLS_TPREL64:
          reloc_status = Reloc_funcs::tlsrel32(view, object, psymval,
                                               elfcpp::TP_OFFSET, r_addend,
                                               extract_addend,
                                               this->calculate_only_,
                                               &this->calculated_value_);
          break;
        case elfcpp::R_MIPS_SUB:
        case elfcpp::R_MICROMIPS_SUB:
          reloc_status = Reloc_funcs::relsub(view, object, psymval, r_addend,
                                             extract_addend,
                                             this->calculate_only_,
                                             &this->calculated_value_);
          break;
        case elfcpp::R_MIPS_HIGHER:
        case elfcpp::R_MICROMIPS_HIGHER:
          reloc_status = Reloc_funcs::relhigher(view, object, psymval, r_addend,
                                                extract_addend,
                                                this->calculate_only_,
                                                &this->calculated_value_);
          break;
        case elfcpp::R_MIPS_HIGHEST:
        case elfcpp::R_MICROMIPS_HIGHEST:
          reloc_status = Reloc_funcs::relhighest(view, object, psymval,
                                                 r_addend, extract_addend,
                                                 this->calculate_only_,
                                                 &this->calculated_value_);
          break;
        default:
          gold_error_at_location(relinfo, relnum, r_offset,
                                 _("unsupported reloc %u"), r_types[i]);
          break;
        }

      if (update_got_entry)
        {
          Mips_output_data_got<size, big_endian>* got = target->got_section();
          if (mips_sym != NULL && mips_sym->get_applied_secondary_got_fixup())
            got->update_got_entry(got->get_primary_got_offset(mips_sym),
                                  psymval->value(object, 0));
          else
            got->update_got_entry(got_offset, psymval->value(object, 0));
        }
    }

  bool jal_shuffle = jal_reloc(r_type);
  Reloc_funcs::mips_reloc_shuffle(view, r_type, jal_shuffle);

  // Report any errors.
  switch (reloc_status)
    {
    case Reloc_funcs::STATUS_OKAY:
      break;
    case Reloc_funcs::STATUS_OVERFLOW:
      if (gsym == NULL)
        gold_error_at_location(relinfo, relnum, r_offset,
                               _("relocation overflow: "
                                 "%u against local symbol %u in %s"),
                               r_type, r_sym, object->name().c_str());
      else if (gsym->is_defined() && gsym->source() == Symbol::FROM_OBJECT)
        gold_error_at_location(relinfo, relnum, r_offset,
                               _("relocation overflow: "
                                 "%u against '%s' defined in %s"),
                               r_type, gsym->demangled_name().c_str(),
                               gsym->object()->name().c_str());
      else
        gold_error_at_location(relinfo, relnum, r_offset,
                               _("relocation overflow: %u against '%s'"),
                               r_type, gsym->demangled_name().c_str());
      break;
    case Reloc_funcs::STATUS_BAD_RELOC:
      gold_error_at_location(relinfo, relnum, r_offset,
        _("unexpected opcode while processing relocation"));
      break;
    case Reloc_funcs::STATUS_PCREL_UNALIGNED:
      gold_error_at_location(relinfo, relnum, r_offset,
        _("unaligned PC-relative relocation"));
      break;
    default:
      gold_unreachable();
    }

  return true;
}

// Get the Reference_flags for a particular relocation.

template<int size, bool big_endian>
int
Target_mips<size, big_endian>::Scan::get_reference_flags(
                       unsigned int r_type)
{
  switch (r_type)
    {
    case elfcpp::R_MIPS_NONE:
      // No symbol reference.
      return 0;

    case elfcpp::R_MIPS_16:
    case elfcpp::R_MIPS_32:
    case elfcpp::R_MIPS_64:
    case elfcpp::R_MIPS_HI16:
    case elfcpp::R_MIPS_LO16:
    case elfcpp::R_MIPS_HIGHER:
    case elfcpp::R_MIPS_HIGHEST:
    case elfcpp::R_MIPS16_HI16:
    case elfcpp::R_MIPS16_LO16:
    case elfcpp::R_MICROMIPS_HI16:
    case elfcpp::R_MICROMIPS_LO16:
    case elfcpp::R_MICROMIPS_HIGHER:
    case elfcpp::R_MICROMIPS_HIGHEST:
      return Symbol::ABSOLUTE_REF;

    case elfcpp::R_MIPS_26:
    case elfcpp::R_MIPS16_26:
    case elfcpp::R_MICROMIPS_26_S1:
      return Symbol::FUNCTION_CALL | Symbol::ABSOLUTE_REF;

    case elfcpp::R_MIPS_PC18_S3:
    case elfcpp::R_MIPS_PC19_S2:
    case elfcpp::R_MIPS_PCHI16:
    case elfcpp::R_MIPS_PCLO16:
    case elfcpp::R_MIPS_GPREL32:
    case elfcpp::R_MIPS_GPREL16:
    case elfcpp::R_MIPS_REL32:
    case elfcpp::R_MIPS16_GPREL:
      return Symbol::RELATIVE_REF;

    case elfcpp::R_MIPS_PC16:
    case elfcpp::R_MIPS_PC32:
    case elfcpp::R_MIPS_PC21_S2:
    case elfcpp::R_MIPS_PC26_S2:
    case elfcpp::R_MIPS_JALR:
    case elfcpp::R_MICROMIPS_JALR:
      return Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;

    case elfcpp::R_MIPS_GOT16:
    case elfcpp::R_MIPS_CALL16:
    case elfcpp::R_MIPS_GOT_DISP:
    case elfcpp::R_MIPS_GOT_HI16:
    case elfcpp::R_MIPS_GOT_LO16:
    case elfcpp::R_MIPS_CALL_HI16:
    case elfcpp::R_MIPS_CALL_LO16:
    case elfcpp::R_MIPS_LITERAL:
    case elfcpp::R_MIPS_GOT_PAGE:
    case elfcpp::R_MIPS_GOT_OFST:
    case elfcpp::R_MIPS16_GOT16:
    case elfcpp::R_MIPS16_CALL16:
    case elfcpp::R_MICROMIPS_GOT16:
    case elfcpp::R_MICROMIPS_CALL16:
    case elfcpp::R_MICROMIPS_GOT_HI16:
    case elfcpp::R_MICROMIPS_GOT_LO16:
    case elfcpp::R_MICROMIPS_CALL_HI16:
    case elfcpp::R_MICROMIPS_CALL_LO16:
    case elfcpp::R_MIPS_EH:
      // Absolute in GOT.
      return Symbol::RELATIVE_REF;

    case elfcpp::R_MIPS_TLS_DTPMOD32:
    case elfcpp::R_MIPS_TLS_DTPREL32:
    case elfcpp::R_MIPS_TLS_DTPMOD64:
    case elfcpp::R_MIPS_TLS_DTPREL64:
    case elfcpp::R_MIPS_TLS_GD:
    case elfcpp::R_MIPS_TLS_LDM:
    case elfcpp::R_MIPS_TLS_DTPREL_HI16:
    case elfcpp::R_MIPS_TLS_DTPREL_LO16:
    case elfcpp::R_MIPS_TLS_GOTTPREL:
    case elfcpp::R_MIPS_TLS_TPREL32:
    case elfcpp::R_MIPS_TLS_TPREL64:
    case elfcpp::R_MIPS_TLS_TPREL_HI16:
    case elfcpp::R_MIPS_TLS_TPREL_LO16:
    case elfcpp::R_MIPS16_TLS_GD:
    case elfcpp::R_MIPS16_TLS_GOTTPREL:
    case elfcpp::R_MICROMIPS_TLS_GD:
    case elfcpp::R_MICROMIPS_TLS_GOTTPREL:
    case elfcpp::R_MICROMIPS_TLS_TPREL_HI16:
    case elfcpp::R_MICROMIPS_TLS_TPREL_LO16:
      return Symbol::TLS_REF;

    case elfcpp::R_MIPS_COPY:
    case elfcpp::R_MIPS_JUMP_SLOT:
    default:
      // Not expected.  We will give an error later.
      return 0;
    }
}

// Report an unsupported relocation against a local symbol.

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

// Report an unsupported relocation against a global symbol.

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

// Return printable name for ABI.
template<int size, bool big_endian>
const char*
Target_mips<size, big_endian>::elf_mips_abi_name(elfcpp::Elf_Word e_flags)
{
  switch (e_flags & elfcpp::EF_MIPS_ABI)
    {
    case 0:
      if ((e_flags & elfcpp::EF_MIPS_ABI2) != 0)
        return "N32";
      else if (size == 64)
        return "64";
      else
        return "none";
    case elfcpp::E_MIPS_ABI_O32:
      return "O32";
    case elfcpp::E_MIPS_ABI_O64:
      return "O64";
    case elfcpp::E_MIPS_ABI_EABI32:
      return "EABI32";
    case elfcpp::E_MIPS_ABI_EABI64:
      return "EABI64";
    default:
      return "unknown abi";
    }
}

template<int size, bool big_endian>
const char*
Target_mips<size, big_endian>::elf_mips_mach_name(elfcpp::Elf_Word e_flags)
{
  switch (e_flags & elfcpp::EF_MIPS_MACH)
    {
    case elfcpp::E_MIPS_MACH_3900:
      return "mips:3900";
    case elfcpp::E_MIPS_MACH_4010:
      return "mips:4010";
    case elfcpp::E_MIPS_MACH_4100:
      return "mips:4100";
    case elfcpp::E_MIPS_MACH_4111:
      return "mips:4111";
    case elfcpp::E_MIPS_MACH_4120:
      return "mips:4120";
    case elfcpp::E_MIPS_MACH_4650:
      return "mips:4650";
    case elfcpp::E_MIPS_MACH_5400:
      return "mips:5400";
    case elfcpp::E_MIPS_MACH_5500:
      return "mips:5500";
    case elfcpp::E_MIPS_MACH_5900:
      return "mips:5900";
    case elfcpp::E_MIPS_MACH_SB1:
      return "mips:sb1";
    case elfcpp::E_MIPS_MACH_9000:
      return "mips:9000";
    case elfcpp::E_MIPS_MACH_LS2E:
      return "mips:loongson_2e";
    case elfcpp::E_MIPS_MACH_LS2F:
      return "mips:loongson_2f";
    case elfcpp::E_MIPS_MACH_LS3A:
      return "mips:loongson_3a";
    case elfcpp::E_MIPS_MACH_OCTEON:
      return "mips:octeon";
    case elfcpp::E_MIPS_MACH_OCTEON2:
      return "mips:octeon2";
    case elfcpp::E_MIPS_MACH_OCTEON3:
      return "mips:octeon3";
    case elfcpp::E_MIPS_MACH_XLR:
      return "mips:xlr";
    default:
      switch (e_flags & elfcpp::EF_MIPS_ARCH)
        {
        default:
        case elfcpp::E_MIPS_ARCH_1:
          return "mips:3000";

        case elfcpp::E_MIPS_ARCH_2:
          return "mips:6000";

        case elfcpp::E_MIPS_ARCH_3:
          return "mips:4000";

        case elfcpp::E_MIPS_ARCH_4:
          return "mips:8000";

        case elfcpp::E_MIPS_ARCH_5:
          return "mips:mips5";

        case elfcpp::E_MIPS_ARCH_32:
          return "mips:isa32";

        case elfcpp::E_MIPS_ARCH_64:
          return "mips:isa64";

        case elfcpp::E_MIPS_ARCH_32R2:
          return "mips:isa32r2";

        case elfcpp::E_MIPS_ARCH_32R6:
          return "mips:isa32r6";

        case elfcpp::E_MIPS_ARCH_64R2:
          return "mips:isa64r2";

        case elfcpp::E_MIPS_ARCH_64R6:
          return "mips:isa64r6";
        }
    }
    return "unknown CPU";
}

template<int size, bool big_endian>
const Target::Target_info Target_mips<size, big_endian>::mips_info =
{
  size,                 // size
  big_endian,           // is_big_endian
  elfcpp::EM_MIPS,      // machine_code
  true,                 // has_make_symbol
  false,                // has_resolve
  false,                // has_code_fill
  true,                 // is_default_stack_executable
  false,                // can_icf_inline_merge_sections
  '\0',                 // wrap_char
  size == 32 ? "/lib/ld.so.1" : "/lib64/ld.so.1",      // dynamic_linker
  0x400000,             // default_text_segment_address
  64 * 1024,            // abi_pagesize (overridable by -z max-page-size)
  4 * 1024,             // common_pagesize (overridable by -z common-page-size)
  false,                // isolate_execinstr
  0,                    // rosegment_gap
  elfcpp::SHN_UNDEF,    // small_common_shndx
  elfcpp::SHN_UNDEF,    // large_common_shndx
  0,                    // small_common_section_flags
  0,                    // large_common_section_flags
  NULL,                 // attributes_section
  NULL,                 // attributes_vendor
  "__start",		// entry_symbol_name
  32,			// hash_entry_size
};

template<int size, bool big_endian>
class Target_mips_nacl : public Target_mips<size, big_endian>
{
 public:
  Target_mips_nacl()
    : Target_mips<size, big_endian>(&mips_nacl_info)
  { }

 private:
  static const Target::Target_info mips_nacl_info;
};

template<int size, bool big_endian>
const Target::Target_info Target_mips_nacl<size, big_endian>::mips_nacl_info =
{
  size,                 // size
  big_endian,           // is_big_endian
  elfcpp::EM_MIPS,      // machine_code
  true,                 // has_make_symbol
  false,                // has_resolve
  false,                // has_code_fill
  true,                 // is_default_stack_executable
  false,                // can_icf_inline_merge_sections
  '\0',                 // wrap_char
  "/lib/ld.so.1",       // dynamic_linker
  0x20000,              // default_text_segment_address
  0x10000,              // abi_pagesize (overridable by -z max-page-size)
  0x10000,              // common_pagesize (overridable by -z common-page-size)
  true,                 // isolate_execinstr
  0x10000000,           // rosegment_gap
  elfcpp::SHN_UNDEF,    // small_common_shndx
  elfcpp::SHN_UNDEF,    // large_common_shndx
  0,                    // small_common_section_flags
  0,                    // large_common_section_flags
  NULL,                 // attributes_section
  NULL,                 // attributes_vendor
  "_start",             // entry_symbol_name
  32,			// hash_entry_size
};

// Target selector for Mips.  Note this is never instantiated directly.
// It's only used in Target_selector_mips_nacl, below.

template<int size, bool big_endian>
class Target_selector_mips : public Target_selector
{
public:
  Target_selector_mips()
    : Target_selector(elfcpp::EM_MIPS, size, big_endian,
                (size == 64 ?
                  (big_endian ? "elf64-tradbigmips" : "elf64-tradlittlemips") :
                  (big_endian ? "elf32-tradbigmips" : "elf32-tradlittlemips")),
                (size == 64 ?
                  (big_endian ? "elf64btsmip" : "elf64ltsmip") :
                  (big_endian ? "elf32btsmip" : "elf32ltsmip")))
  { }

  Target* do_instantiate_target()
  { return new Target_mips<size, big_endian>(); }
};

template<int size, bool big_endian>
class Target_selector_mips_nacl
  : public Target_selector_nacl<Target_selector_mips<size, big_endian>,
                                Target_mips_nacl<size, big_endian> >
{
 public:
  Target_selector_mips_nacl()
    : Target_selector_nacl<Target_selector_mips<size, big_endian>,
                           Target_mips_nacl<size, big_endian> >(
        // NaCl currently supports only MIPS32 little-endian.
        "mipsel", "elf32-tradlittlemips-nacl", "elf32-tradlittlemips-nacl")
  { }
};

Target_selector_mips_nacl<32, true> target_selector_mips32;
Target_selector_mips_nacl<32, false> target_selector_mips32el;
Target_selector_mips_nacl<64, true> target_selector_mips64;
Target_selector_mips_nacl<64, false> target_selector_mips64el;

} // End anonymous namespace.
