Refactor gold to enable support for MIPS-64 relocation format.
[deliverable/binutils-gdb.git] / gold / mips.cc
index 3d513fff17204632c0d14effc00a93348cb39257..c57ef4f807f4a51ade8a46ed822ef1267acc80a1 100644 (file)
@@ -2642,9 +2642,9 @@ class Mips_output_section_reginfo : public Output_section
 // 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, int sh_type, typename Classify_reloc>
+template<bool big_endian, typename Classify_reloc>
 class Mips_scan_relocatable_relocs :
-  public Default_scan_relocatable_relocs<sh_type, Classify_reloc>
+  public Default_scan_relocatable_relocs<Classify_reloc>
 {
  public:
   // Return the strategy to use for a local symbol which is a section
@@ -2652,7 +2652,7 @@ class Mips_scan_relocatable_relocs :
   inline Relocatable_relocs::Reloc_strategy
   local_section_strategy(unsigned int r_type, Relobj* object)
   {
-    if (sh_type == elfcpp::SHT_RELA)
+    if (Classify_reloc::sh_type == elfcpp::SHT_RELA)
       return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA;
     else
       {
@@ -2662,7 +2662,7 @@ class Mips_scan_relocatable_relocs :
             return Relocatable_relocs::RELOC_SPECIAL;
 
           default:
-            return Default_scan_relocatable_relocs<sh_type, Classify_reloc>::
+            return Default_scan_relocatable_relocs<Classify_reloc>::
                 local_section_strategy(r_type, object);
           }
       }
@@ -2860,6 +2860,182 @@ class Symbol_visitor_check_symbols
   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 unsigned 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 unsigned 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 unsigned 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 unsigned 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()); }
+
+  // Return the explicit addend of the relocation (return 0 for SHT_REL).
+  static inline unsigned int
+  get_r_addend(const Reltype* reloc)
+  { 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<64>(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 type of the relocation.
+  static inline unsigned int
+  get_r_type(const Reltype* reloc)
+  { return reloc->get_r_type(); }
+
+  // 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)
+  { 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>
 {
@@ -2870,6 +3046,10 @@ class Target_mips : public Sized_target<size, big_endian>
     Reloca_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)
@@ -2955,6 +3135,21 @@ class Target_mips : public Sized_target<size, big_endian>
                           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>*,
@@ -3164,6 +3359,17 @@ class Target_mips : public Sized_target<size, big_endian>
   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
@@ -3268,7 +3474,7 @@ class Target_mips : public Sized_target<size, big_endian>
           Sized_relobj_file<size, big_endian>* object,
           unsigned int data_shndx,
           Output_section* output_section,
-          const elfcpp::Rel<size, big_endian>& reloc, unsigned int r_type,
+          const Reltype& reloc, unsigned int r_type,
           const elfcpp::Sym<size, big_endian>& lsym,
           bool is_discarded);
 
@@ -3277,7 +3483,7 @@ class Target_mips : public Sized_target<size, big_endian>
           Sized_relobj_file<size, big_endian>* object,
           unsigned int data_shndx,
           Output_section* output_section,
-          const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
+          const Relatype& reloc, unsigned int r_type,
           const elfcpp::Sym<size, big_endian>& lsym,
           bool is_discarded);
 
@@ -3286,8 +3492,8 @@ class Target_mips : public Sized_target<size, big_endian>
           Sized_relobj_file<size, big_endian>* object,
           unsigned int data_shndx,
           Output_section* output_section,
-          const elfcpp::Rela<size, big_endian>* rela,
-          const elfcpp::Rel<size, big_endian>* rel,
+          const Relatype* rela,
+          const Reltype* rel,
           unsigned int rel_type,
           unsigned int r_type,
           const elfcpp::Sym<size, big_endian>& lsym,
@@ -3298,7 +3504,7 @@ class Target_mips : public Sized_target<size, big_endian>
            Sized_relobj_file<size, big_endian>* object,
            unsigned int data_shndx,
            Output_section* output_section,
-           const elfcpp::Rel<size, big_endian>& reloc, unsigned int r_type,
+           const Reltype& reloc, unsigned int r_type,
            Symbol* gsym);
 
     inline void
@@ -3306,7 +3512,7 @@ class Target_mips : public Sized_target<size, big_endian>
            Sized_relobj_file<size, big_endian>* object,
            unsigned int data_shndx,
            Output_section* output_section,
-           const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
+           const Relatype& reloc, unsigned int r_type,
            Symbol* gsym);
 
     inline void
@@ -3314,8 +3520,8 @@ class Target_mips : public Sized_target<size, big_endian>
            Sized_relobj_file<size, big_endian>* object,
            unsigned int data_shndx,
            Output_section* output_section,
-           const elfcpp::Rela<size, big_endian>* rela,
-           const elfcpp::Rel<size, big_endian>* rel,
+           const Relatype* rela,
+           const Reltype* rel,
            unsigned int rel_type,
            unsigned int r_type,
            Symbol* gsym);
@@ -3326,7 +3532,7 @@ class Target_mips : public Sized_target<size, big_endian>
                                         Sized_relobj_file<size, big_endian>*,
                                         unsigned int,
                                         Output_section*,
-                                        const elfcpp::Rel<size, big_endian>&,
+                                        const Reltype&,
                                         unsigned int,
                                         const elfcpp::Sym<size, big_endian>&)
     { return false; }
@@ -3337,7 +3543,7 @@ class Target_mips : public Sized_target<size, big_endian>
                                          Sized_relobj_file<size, big_endian>*,
                                          unsigned int,
                                          Output_section*,
-                                         const elfcpp::Rel<size, big_endian>&,
+                                         const Reltype&,
                                          unsigned int, Symbol*)
     { return false; }
 
@@ -3347,7 +3553,7 @@ class Target_mips : public Sized_target<size, big_endian>
                                         Sized_relobj_file<size, big_endian>*,
                                         unsigned int,
                                         Output_section*,
-                                        const elfcpp::Rela<size, big_endian>&,
+                                        const Relatype&,
                                         unsigned int,
                                         const elfcpp::Sym<size, big_endian>&)
     { return false; }
@@ -3358,7 +3564,7 @@ class Target_mips : public Sized_target<size, big_endian>
                                          Sized_relobj_file<size, big_endian>*,
                                          unsigned int,
                                          Output_section*,
-                                         const elfcpp::Rela<size, big_endian>&,
+                                         const Relatype&,
                                          unsigned int, Symbol*)
     { return false; }
    private:
@@ -3397,15 +3603,6 @@ class Target_mips : public Sized_target<size, big_endian>
             unsigned char*, Mips_address, section_size_type);
   };
 
-  // A class which returns the size required for a relocation type,
-  // used while scanning relocs during a relocatable link.
-  class Relocatable_size_for_reloc
-  {
-   public:
-    unsigned int
-    get_size_for_reloc(unsigned int, Relobj*);
-  };
-
   // 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
@@ -3573,9 +3770,11 @@ class Target_mips : public Sized_target<size, big_endian>
   copy_reloc(Symbol_table* symtab, Layout* layout,
              Sized_relobj_file<size, big_endian>* object,
              unsigned int shndx, Output_section* output_section,
-             Symbol* sym, const elfcpp::Rel<size, big_endian>& reloc)
+             Symbol* sym, const Reltype& reloc)
   {
-    unsigned int r_type = elfcpp::elf_r_type<size>(reloc.get_r_info());
+    unsigned int r_type =
+       Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>::
+         get_r_type(&reloc);
     this->copy_relocs_.copy_reloc(symtab, layout,
                                   symtab->get_sized_symbol<size>(sym),
                                   object, shndx, output_section,
@@ -3725,7 +3924,6 @@ class Target_mips : public Sized_target<size, big_endian>
   bool insn32_;
 };
 
-
 // Helper structure for R_MIPS*_HI16/LO16 and R_MIPS*_GOT16/LO16 relocations.
 // It records high part of the relocation pair.
 
@@ -7510,10 +7708,10 @@ Target_mips<size, big_endian>::gc_process_relocs(
                         const unsigned char* plocal_symbols)
 {
   typedef Target_mips<size, big_endian> Mips;
-  typedef typename Target_mips<size, big_endian>::Scan Scan;
+  typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>
+      Classify_reloc;
 
-  gold::gc_process_relocs<size, big_endian, Mips, elfcpp::SHT_REL, Scan,
-                          typename Target_mips::Relocatable_size_for_reloc>(
+  gold::gc_process_relocs<size, big_endian, Mips, Scan, Classify_reloc>(
     symtab,
     layout,
     this,
@@ -7545,34 +7743,43 @@ Target_mips<size, big_endian>::scan_relocs(
                         const unsigned char* plocal_symbols)
 {
   typedef Target_mips<size, big_endian> Mips;
-  typedef typename Target_mips<size, big_endian>::Scan Scan;
 
   if (sh_type == elfcpp::SHT_REL)
-    gold::scan_relocs<size, big_endian, Mips, elfcpp::SHT_REL, Scan>(
-      symtab,
-      layout,
-      this,
-      object,
-      data_shndx,
-      prelocs,
-      reloc_count,
-      output_section,
-      needs_special_offset_handling,
-      local_symbol_count,
-      plocal_symbols);
+    {
+      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)
-    gold::scan_relocs<size, big_endian, Mips, elfcpp::SHT_RELA, Scan>(
-      symtab,
-      layout,
-      this,
-      object,
-      data_shndx,
-      prelocs,
-      reloc_count,
-      output_section,
-      needs_special_offset_handling,
-      local_symbol_count,
-      plocal_symbols);
+    {
+      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>
@@ -8227,41 +8434,48 @@ Target_mips<size, big_endian>::relocate_section(
   typedef typename Target_mips<size, big_endian>::Relocate Mips_relocate;
 
   if (sh_type == elfcpp::SHT_REL)
-    gold::relocate_section<size, big_endian, Mips, elfcpp::SHT_REL,
-      Mips_relocate, gold::Default_comdat_behavior>(
-      relinfo,
-      this,
-      prelocs,
-      reloc_count,
-      output_section,
-      needs_special_offset_handling,
-      view,
-      address,
-      view_size,
-      reloc_symbol_changes);
+    {
+      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)
-    gold::relocate_section<size, big_endian, Mips, elfcpp::SHT_RELA,
-      Mips_relocate, gold::Default_comdat_behavior>(
-      relinfo,
-      this,
-      prelocs,
-      reloc_count,
-      output_section,
-      needs_special_offset_handling,
-      view,
-      address,
-      view_size,
-      reloc_symbol_changes);
+    {
+      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.
 
-template<int size, bool big_endian>
 unsigned int
-Target_mips<size, big_endian>::Relocatable_size_for_reloc::get_size_for_reloc(
-    unsigned int r_type,
-    Relobj* object)
+mips_get_size_for_reloc(unsigned int r_type, Relobj* object)
 {
   switch (r_type)
     {
@@ -8344,13 +8558,14 @@ Target_mips<size, big_endian>::scan_relocatable_relocs(
                         const unsigned char* plocal_symbols,
                         Relocatable_relocs* rr)
 {
-  gold_assert(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;
 
-  typedef Mips_scan_relocatable_relocs<big_endian, elfcpp::SHT_REL,
-    Relocatable_size_for_reloc> Scan_relocatable_relocs;
+  gold_assert(sh_type == elfcpp::SHT_REL);
 
-  gold::scan_relocatable_relocs<size, big_endian, elfcpp::SHT_REL,
-    Scan_relocatable_relocs>(
+  gold::scan_relocatable_relocs<size, big_endian, Scan_relocatable_relocs>(
     symtab,
     layout,
     object,
@@ -8364,6 +8579,45 @@ Target_mips<size, big_endian>::scan_relocatable_relocs(
     rr);
 }
 
+// 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)
+{
+  typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>
+      Classify_reloc;
+  typedef gold::Default_emit_relocs_strategy<Classify_reloc>
+      Emit_relocs_strategy;
+
+  gold_assert(sh_type == elfcpp::SHT_REL);
+
+  gold::scan_relocatable_relocs<size, big_endian, Emit_relocs_strategy>(
+    symtab,
+    layout,
+    object,
+    data_shndx,
+    prelocs,
+    reloc_count,
+    output_section,
+    needs_special_offset_handling,
+    local_symbol_count,
+    plocal_syms,
+    rr);
+}
+
 // Emit relocations for a section.
 
 template<int size, bool big_endian>
@@ -8382,9 +8636,12 @@ Target_mips<size, big_endian>::relocate_relocs(
                         unsigned char* reloc_view,
                         section_size_type reloc_view_size)
 {
+  typedef Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>
+      Classify_reloc;
+
   gold_assert(sh_type == elfcpp::SHT_REL);
 
-  gold::relocate_relocs<size, big_endian, elfcpp::SHT_REL>(
+  gold::relocate_relocs<size, big_endian, Classify_reloc>(
     relinfo,
     prelocs,
     reloc_count,
@@ -8550,8 +8807,8 @@ Target_mips<size, big_endian>::Scan::local(
                         Sized_relobj_file<size, big_endian>* object,
                         unsigned int data_shndx,
                         Output_section* output_section,
-                        const elfcpp::Rela<size, big_endian>* rela,
-                        const elfcpp::Rel<size, big_endian>* rel,
+                        const Relatype* rela,
+                        const Reltype* rel,
                         unsigned int rel_type,
                         unsigned int r_type,
                         const elfcpp::Sym<size, big_endian>& lsym,
@@ -8561,23 +8818,24 @@ Target_mips<size, big_endian>::Scan::local(
     return;
 
   Mips_address r_offset;
-  typename elfcpp::Elf_types<size>::Elf_WXword r_info;
+  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_info = rela->get_r_info();
+      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_info = rel->get_r_info();
+      r_sym = Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>::
+         get_r_sym(rel);
       r_addend = 0;
     }
 
-  unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
   Mips_relobj<size, big_endian>* mips_obj =
     Mips_relobj<size, big_endian>::as_mips_relobj(object);
 
@@ -8655,7 +8913,6 @@ Target_mips<size, big_endian>::Scan::local(
       // R_MIPS_GOT_LO16 or R_MIPS_CALL_LO16.
       Mips_output_data_got<size, big_endian>* got =
         target->got_section(symtab, layout);
-      unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
       got->record_local_got_symbol(mips_obj, r_sym, r_addend, r_type, -1U);
     }
 
@@ -8790,7 +9047,6 @@ Target_mips<size, big_endian>::Scan::local(
             // executable), we need to create a dynamic relocation for
             // this location.
             Reloc_section* rel_dyn = target->rel_dyn_section(layout);
-            unsigned int r_sym = elfcpp::elf_r_sym<32>(r_info);
             rel_dyn->add_symbolless_local_addend(object, r_sym,
                                                  elfcpp::R_MIPS_REL32,
                                                  output_section, data_shndx,
@@ -8809,7 +9065,6 @@ Target_mips<size, big_endian>::Scan::local(
     case elfcpp::R_MIPS16_TLS_GD:
     case elfcpp::R_MICROMIPS_TLS_GD:
       {
-        unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
         bool output_is_shared = parameters->options().shared();
         const tls::Tls_optimization optimized_type
             = Target_mips<size, big_endian>::optimize_tls_reloc(
@@ -8929,7 +9184,7 @@ Target_mips<size, big_endian>::Scan::local(
                         Sized_relobj_file<size, big_endian>* object,
                         unsigned int data_shndx,
                         Output_section* output_section,
-                        const elfcpp::Rel<size, big_endian>& reloc,
+                        const Reltype& reloc,
                         unsigned int r_type,
                         const elfcpp::Sym<size, big_endian>& lsym,
                         bool is_discarded)
@@ -8944,7 +9199,7 @@ Target_mips<size, big_endian>::Scan::local(
     object,
     data_shndx,
     output_section,
-    (const elfcpp::Rela<size, big_endian>*) NULL,
+    (const Relatype*) NULL,
     &reloc,
     elfcpp::SHT_REL,
     r_type,
@@ -8961,7 +9216,7 @@ Target_mips<size, big_endian>::Scan::local(
                         Sized_relobj_file<size, big_endian>* object,
                         unsigned int data_shndx,
                         Output_section* output_section,
-                        const elfcpp::Rela<size, big_endian>& reloc,
+                        const Relatype& reloc,
                         unsigned int r_type,
                         const elfcpp::Sym<size, big_endian>& lsym,
                         bool is_discarded)
@@ -8977,7 +9232,7 @@ Target_mips<size, big_endian>::Scan::local(
     data_shndx,
     output_section,
     &reloc,
-    (const elfcpp::Rel<size, big_endian>*) NULL,
+    (const Reltype*) NULL,
     elfcpp::SHT_RELA,
     r_type,
     lsym, is_discarded);
@@ -8994,30 +9249,31 @@ Target_mips<size, big_endian>::Scan::global(
                                 Sized_relobj_file<size, big_endian>* object,
                                 unsigned int data_shndx,
                                 Output_section* output_section,
-                                const elfcpp::Rela<size, big_endian>* rela,
-                                const elfcpp::Rel<size, big_endian>* rel,
+                                const Relatype* rela,
+                                const Reltype* rel,
                                 unsigned int rel_type,
                                 unsigned int r_type,
                                 Symbol* gsym)
 {
   Mips_address r_offset;
-  typename elfcpp::Elf_types<size>::Elf_WXword r_info;
+  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_info = rela->get_r_info();
+      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_info = rel->get_r_info();
+      r_sym = Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>::
+         get_r_sym(rel);
       r_addend = 0;
     }
 
-  unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
   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);
@@ -9434,7 +9690,7 @@ Target_mips<size, big_endian>::Scan::global(
                                 Sized_relobj_file<size, big_endian>* object,
                                 unsigned int data_shndx,
                                 Output_section* output_section,
-                                const elfcpp::Rela<size, big_endian>& reloc,
+                                const Relatype& reloc,
                                 unsigned int r_type,
                                 Symbol* gsym)
 {
@@ -9446,7 +9702,7 @@ Target_mips<size, big_endian>::Scan::global(
     data_shndx,
     output_section,
     &reloc,
-    (const elfcpp::Rel<size, big_endian>*) NULL,
+    (const Reltype*) NULL,
     elfcpp::SHT_RELA,
     r_type,
     gsym);
@@ -9461,7 +9717,7 @@ Target_mips<size, big_endian>::Scan::global(
                                 Sized_relobj_file<size, big_endian>* object,
                                 unsigned int data_shndx,
                                 Output_section* output_section,
-                                const elfcpp::Rel<size, big_endian>& reloc,
+                                const Reltype& reloc,
                                 unsigned int r_type,
                                 Symbol* gsym)
 {
@@ -9472,7 +9728,7 @@ Target_mips<size, big_endian>::Scan::global(
     object,
     data_shndx,
     output_section,
-    (const elfcpp::Rela<size, big_endian>*) NULL,
+    (const Relatype*) NULL,
     &reloc,
     elfcpp::SHT_REL,
     r_type,
@@ -9546,32 +9802,38 @@ Target_mips<size, big_endian>::Relocate::relocate(
                         section_size_type)
 {
   Mips_address r_offset;
-  typename elfcpp::Elf_types<size>::Elf_WXword r_info;
+  unsigned int r_sym;
+  unsigned int r_type;
   typename elfcpp::Elf_types<size>::Elf_Swxword r_addend;
 
   if (rel_type == elfcpp::SHT_RELA)
     {
-      const elfcpp::Rela<size, big_endian> rela(preloc);
+      const Relatype rela(preloc);
       r_offset = rela.get_r_offset();
-      r_info = rela.get_r_info();
+      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_addend = rela.get_r_addend();
     }
   else
     {
-      const elfcpp::Rel<size, big_endian> rel(preloc);
+
+      const Reltype rel(preloc);
       r_offset = rel.get_r_offset();
-      r_info = rel.get_r_info();
+      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_addend = 0;
     }
-  unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
 
   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);
+      Mips_relobj<size, big_endian>::as_mips_relobj(relinfo->object);
 
-  unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
   bool target_is_16_bit_code = false;
   bool target_is_micromips_code = false;
   bool cross_mode_jump;
This page took 0.036866 seconds and 4 git commands to generate.