[GOLD] Relocate::relocate() params
authorAlan Modra <amodra@gmail.com>
Tue, 8 Dec 2015 23:48:30 +0000 (10:18 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 9 Dec 2015 00:06:43 +0000 (10:36 +1030)
Some linker code editing needs to change multiple insns.  In some
cases multiple relocations are involved and it is not sufficient to
make the changes independently as relocations are processed, because
doing so might lead to a partial edit.  So in order to safely edit we
need all the relocations available in relocate().  Also, to emit
edited relocs corresponding to the edited code sequence we need some
way to pass information from relocate() to relocate_relocs(),
particularly if the edit depends on insns.  We can't modify input
relocs in relocate() as they are mmapped PROT_READ, nor it is
particularly clean to write relocs to the output at that stage.  So
add a Relocatable_relocs* field to relinfo to mark edited relocs.

Given that relocate is passed the raw reloc pointer, it makes sense to
remove the rel/rela parameter and r_type too.  However, that means the
mips relocate() needs to know whether SHT_REL or SHT_RELA relocs are
being processed.  So add a rel_type for mips, which also has the
benefit of removing relocate() overloading there.

This patch adds the infrastructure without making use of it.

Note that relinfo->rr will be NULL if not outputting relocations.

* object.h (struct Relocate_info): Add "rr".
* reloc.h (Relocatable_relocs::set_strategy): New accessor.
* reloc.cc (Sized_relobj_file::do_relocate_sections): Init
relinfo.rr for relocate_section and relocate_relocs.
* powerpc.cc (relocate): Add rel_type and preloc parameters.
Delete rela and r_type params, instead recalculate these from
preloc.
(relocate_relocs): Delete Relocatable_relocs* param, instead
use relinfo->rr.
* aarch64.cc: Likewise.
* arm.cc: Likewise.
* i386.cc: Likewise.
* mips.cc: Likewise.
* s390.cc: Likewise.
* sparc.cc: Likewise.
* target.h: Likewise.
* tilegx.cc: Likewise.
* x86_64.cc: Likewise.
* testsuite/testfile.cc: Likewise.
* target-reloc.h (relocate_section): Adjust to suit.
(apply_relocation, relocate_relocs): Likewise.

16 files changed:
gold/ChangeLog
gold/aarch64.cc
gold/arm.cc
gold/i386.cc
gold/mips.cc
gold/object.h
gold/powerpc.cc
gold/reloc.cc
gold/reloc.h
gold/s390.cc
gold/sparc.cc
gold/target-reloc.h
gold/target.h
gold/testsuite/testfile.cc
gold/tilegx.cc
gold/x86_64.cc

index c4bf4a4d24bbb89df4ca97a8ae56cbd3a4e77cb0..be004cd1e550753cb18703414eec850afdd951ef 100644 (file)
@@ -1,3 +1,27 @@
+2015-12-09  Alan Modra  <amodra@gmail.com>
+
+       * object.h (struct Relocate_info): Add "rr".
+       * reloc.h (Relocatable_relocs::set_strategy): New accessor.
+       * reloc.cc (Sized_relobj_file::do_relocate_sections): Init
+       relinfo.rr for relocate_section and relocate_relocs.
+       * powerpc.cc (relocate): Add rel_type and preloc parameters.
+       Delete rela and r_type params, instead recalculate these from
+       preloc.
+       (relocate_relocs): Delete Relocatable_relocs* param, instead
+       use relinfo->rr.
+       * aarch64.cc: Likewise.
+       * arm.cc: Likewise.
+       * i386.cc: Likewise.
+       * mips.cc: Likewise.
+       * s390.cc: Likewise.
+       * sparc.cc: Likewise.
+       * target.h: Likewise.
+       * tilegx.cc: Likewise.
+       * x86_64.cc: Likewise.
+       * testsuite/testfile.cc: Likewise.
+       * target-reloc.h (relocate_section): Adjust to suit.
+       (apply_relocation, relocate_relocs): Likewise.
+
 2015-12-07  Alan Modra  <amodra@gmail.com>
 
        * powerpc.cc (add_2_2_12, ld_2_12, lis_2): Define.
index 5ca5e0accfff921463a4714224802ba0099d6d71..9fdec40311c112fa12a116c39c3e2ccf1fd0ee7d 100644 (file)
@@ -2878,7 +2878,6 @@ class Target_aarch64 : public Sized_target<size, big_endian>
       size_t reloc_count,
       Output_section* output_section,
       typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
-      const Relocatable_relocs*,
       unsigned char* view,
       typename elfcpp::Elf_types<size>::Elf_Addr view_address,
       section_size_type view_size,
@@ -3157,11 +3156,9 @@ class Target_aarch64 : public Sized_target<size, big_endian>
     // 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>*, Target_aarch64*,
-            Output_section*,
-            size_t relnum, const elfcpp::Rela<size, big_endian>&,
-            unsigned int r_type, const Sized_symbol<size>*,
-            const Symbol_value<size>*,
+    relocate(const Relocate_info<size, big_endian>*, unsigned int,
+            Target_aarch64*, Output_section*, size_t, const unsigned char*,
+            const Sized_symbol<size>*, const Symbol_value<size>*,
             unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr,
             section_size_type);
 
@@ -6812,11 +6809,11 @@ template<int size, bool big_endian>
 inline bool
 Target_aarch64<size, big_endian>::Relocate::relocate(
     const Relocate_info<size, big_endian>* relinfo,
+    unsigned int,
     Target_aarch64<size, big_endian>* target,
     Output_section* ,
     size_t relnum,
-    const elfcpp::Rela<size, big_endian>& rela,
-    unsigned int r_type,
+    const unsigned char* preloc,
     const Sized_symbol<size>* gsym,
     const Symbol_value<size>* psymval,
     unsigned char* view,
@@ -6828,6 +6825,8 @@ Target_aarch64<size, big_endian>::Relocate::relocate(
 
   typedef AArch64_relocate_functions<size, big_endian> Reloc;
 
+  const elfcpp::Rela<size, big_endian> rela(preloc);
+  unsigned int r_type = elfcpp::elf_r_type<size>(rela.get_r_info());
   const AArch64_reloc_property* reloc_property =
       aarch64_reloc_property_table->get_reloc_property(r_type);
 
@@ -7949,7 +7948,6 @@ Target_aarch64<size, big_endian>::relocate_relocs(
     size_t reloc_count,
     Output_section* output_section,
     typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
-    const Relocatable_relocs* rr,
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr view_address,
     section_size_type view_size,
@@ -7964,7 +7962,6 @@ Target_aarch64<size, big_endian>::relocate_relocs(
     reloc_count,
     output_section,
     offset_in_output_section,
-    rr,
     view,
     view_address,
     view_size,
index 4a6d41443209af249e03c189625bc01b54f9387a..33e873497d7421e2bfc0bbc5792d0688c0e2602c 100644 (file)
@@ -2307,7 +2307,6 @@ class Target_arm : public Sized_target<32, big_endian>
                  Output_section* output_section,
                  typename elfcpp::Elf_types<32>::Elf_Off
                     offset_in_output_section,
-                 const Relocatable_relocs*,
                  unsigned char* view,
                  Arm_address view_address,
                  section_size_type view_size,
@@ -2669,13 +2668,10 @@ class Target_arm : public Sized_target<32, big_endian>
     // Do a relocation.  Return false if the caller should not issue
     // any warnings about this relocation.
     inline bool
-    relocate(const Relocate_info<32, big_endian>*, Target_arm*,
-            Output_section*,  size_t relnum,
-            const elfcpp::Rel<32, big_endian>&,
-            unsigned int r_type, const Sized_symbol<32>*,
-            const Symbol_value<32>*,
-            unsigned char*, Arm_address,
-            section_size_type);
+    relocate(const Relocate_info<32, big_endian>*, unsigned int,
+            Target_arm*, Output_section*, size_t, const unsigned char*,
+            const Sized_symbol<32>*, const Symbol_value<32>*,
+            unsigned char*, Arm_address, section_size_type);
 
     // Return whether we want to pass flag NON_PIC_REF for this
     // reloc.  This means the relocation type accesses a symbol not via
@@ -9323,11 +9319,11 @@ template<bool big_endian>
 inline bool
 Target_arm<big_endian>::Relocate::relocate(
     const Relocate_info<32, big_endian>* relinfo,
+    unsigned int,
     Target_arm* target,
     Output_section* output_section,
     size_t relnum,
-    const elfcpp::Rel<32, big_endian>& rel,
-    unsigned int r_type,
+    const unsigned char* preloc,
     const Sized_symbol<32>* gsym,
     const Symbol_value<32>* psymval,
     unsigned char* view,
@@ -9339,6 +9335,8 @@ Target_arm<big_endian>::Relocate::relocate(
 
   typedef Arm_relocate_functions<big_endian> Arm_relocate_functions;
 
+  const elfcpp::Rel<32, big_endian> rel(preloc);
+  unsigned int r_type = elfcpp::elf_r_type<32>(rel.get_r_info());
   r_type = get_real_reloc_type(r_type);
   const Arm_reloc_property* reloc_property =
     arm_reloc_property_table->get_implemented_static_reloc_property(r_type);
@@ -10113,7 +10111,6 @@ Target_arm<big_endian>::relocate_relocs(
     size_t reloc_count,
     Output_section* output_section,
     typename elfcpp::Elf_types<32>::Elf_Off offset_in_output_section,
-    const Relocatable_relocs* rr,
     unsigned char* view,
     Arm_address view_address,
     section_size_type view_size,
@@ -10128,7 +10125,6 @@ Target_arm<big_endian>::relocate_relocs(
     reloc_count,
     output_section,
     offset_in_output_section,
-    rr,
     view,
     view_address,
     view_size,
@@ -12282,10 +12278,9 @@ Target_arm<big_endian>::relocate_stub(
       elfcpp::Rel_write<32, big_endian> reloc_write(reloc_buffer);
       reloc_write.put_r_offset(reloc_offset);
       reloc_write.put_r_info(elfcpp::elf_r_info<32>(0, r_type));
-      elfcpp::Rel<32, big_endian> rel(reloc_buffer);
 
-      relocate.relocate(relinfo, this, output_section,
-                       this->fake_relnum_for_stubs, rel, r_type,
+      relocate.relocate(relinfo, elfcpp::SHT_REL, this, output_section,
+                       this->fake_relnum_for_stubs, reloc_buffer,
                        NULL, &symval, view + reloc_offset,
                        address + reloc_offset, reloc_size);
     }
index 4f41be4a61731610a10ef175a0b3130c94d1d094..8cc724460cadfed2c40081a51195e52b896e0ae9 100644 (file)
@@ -437,7 +437,6 @@ class Target_i386 : public Sized_target<32, false>
                  size_t reloc_count,
                  Output_section* output_section,
                  elfcpp::Elf_types<32>::Elf_Off offset_in_output_section,
-                 const Relocatable_relocs*,
                  unsigned char* view,
                  elfcpp::Elf_types<32>::Elf_Addr view_address,
                  section_size_type view_size,
@@ -634,10 +633,9 @@ class Target_i386 : public Sized_target<32, false>
     // Do a relocation.  Return false if the caller should not issue
     // any warnings about this relocation.
     inline bool
-    relocate(const Relocate_info<32, false>*, Target_i386*, Output_section*,
-            size_t relnum, const elfcpp::Rel<32, false>&,
-            unsigned int r_type, const Sized_symbol<32>*,
-            const Symbol_value<32>*,
+    relocate(const Relocate_info<32, false>*, unsigned int,
+            Target_i386*, Output_section*, size_t, const unsigned char*,
+            const Sized_symbol<32>*, const Symbol_value<32>*,
             unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
             section_size_type);
 
@@ -2732,17 +2730,20 @@ Target_i386::Relocate::should_apply_static_reloc(const Sized_symbol<32>* gsym,
 
 inline bool
 Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
-                                      Target_i386* target,
-                                      Output_section* output_section,
-                                      size_t relnum,
-                                      const elfcpp::Rel<32, false>& rel,
-                                      unsigned int r_type,
-                                      const Sized_symbol<32>* gsym,
-                                      const Symbol_value<32>* psymval,
-                                      unsigned char* view,
-                                      elfcpp::Elf_types<32>::Elf_Addr address,
-                                      section_size_type view_size)
+                               unsigned int,
+                               Target_i386* target,
+                               Output_section* output_section,
+                               size_t relnum,
+                               const unsigned char* preloc,
+                               const Sized_symbol<32>* gsym,
+                               const Symbol_value<32>* psymval,
+                               unsigned char* view,
+                               elfcpp::Elf_types<32>::Elf_Addr address,
+                               section_size_type view_size)
 {
+  const elfcpp::Rel<32, false> rel(preloc);
+  unsigned int r_type = elfcpp::elf_r_type<32>(rel.get_r_info());
+
   if (this->skip_call_tls_get_addr_)
     {
       if ((r_type != elfcpp::R_386_PLT32
@@ -3740,7 +3741,6 @@ Target_i386::relocate_relocs(
     size_t reloc_count,
     Output_section* output_section,
     elfcpp::Elf_types<32>::Elf_Off offset_in_output_section,
-    const Relocatable_relocs* rr,
     unsigned char* view,
     elfcpp::Elf_types<32>::Elf_Addr view_address,
     section_size_type view_size,
@@ -3755,7 +3755,6 @@ Target_i386::relocate_relocs(
     reloc_count,
     output_section,
     offset_in_output_section,
-    rr,
     view,
     view_address,
     view_size,
index 051d49a1d3fdffd0398cba0cbae96b1ca798246a..af4c9af5fe602439747e831bd98d6d3208ab1437 100644 (file)
@@ -2964,7 +2964,6 @@ class Target_mips : public Sized_target<size, big_endian>
                   Output_section* output_section,
                   typename elfcpp::Elf_types<size>::Elf_Off
                     offset_in_output_section,
-                  const Relocatable_relocs*,
                   unsigned char* view,
                   Mips_address view_address,
                   section_size_type view_size,
@@ -3392,36 +3391,10 @@ class Target_mips : public Sized_target<size, big_endian>
     // 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>*, Target_mips*,
-             Output_section*, size_t relnum,
-             const elfcpp::Rela<size, big_endian>*,
-             const elfcpp::Rel<size, big_endian>*,
-             unsigned int,
-             unsigned int,  const Sized_symbol<size>*,
-             const Symbol_value<size>*,
-             unsigned char*,
-             Mips_address,
-             section_size_type);
-
-    inline bool
-    relocate(const Relocate_info<size, big_endian>*, Target_mips*,
-             Output_section*, size_t relnum,
-             const elfcpp::Rel<size, big_endian>&,
-             unsigned int, const Sized_symbol<size>*,
-             const Symbol_value<size>*,
-             unsigned char*,
-             Mips_address,
-             section_size_type);
-
-    inline bool
-    relocate(const Relocate_info<size, big_endian>*, Target_mips*,
-             Output_section*, size_t relnum,
-             const elfcpp::Rela<size, big_endian>&,
-             unsigned int, const Sized_symbol<size>*,
-             const Symbol_value<size>*,
-             unsigned char*,
-             Mips_address,
-             section_size_type);
+    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);
   };
 
   // A class which returns the size required for a relocation type,
@@ -8278,7 +8251,7 @@ Target_mips<size, big_endian>::relocate_section(
       view,
       address,
       view_size,
-     reloc_symbol_changes);
+      reloc_symbol_changes);
 }
 
 // Return the size of a relocation while scanning during a relocatable
@@ -8403,7 +8376,6 @@ Target_mips<size, big_endian>::relocate_relocs(
                         Output_section* output_section,
                         typename elfcpp::Elf_types<size>::Elf_Off
                           offset_in_output_section,
-                        const Relocatable_relocs* rr,
                         unsigned char* view,
                         Mips_address view_address,
                         section_size_type view_size,
@@ -8418,7 +8390,6 @@ Target_mips<size, big_endian>::relocate_relocs(
     reloc_count,
     output_section,
     offset_in_output_section,
-    rr,
     view,
     view_address,
     view_size,
@@ -9563,13 +9534,11 @@ 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 elfcpp::Rela<size, big_endian>* rela,
-                        const elfcpp::Rel<size, big_endian>* rel,
-                        unsigned int rel_type,
-                        unsigned int r_type,
+                        const unsigned char* preloc,
                         const Sized_symbol<size>* gsym,
                         const Symbol_value<size>* psymval,
                         unsigned char* view,
@@ -9582,16 +9551,19 @@ Target_mips<size, big_endian>::Relocate::relocate(
 
   if (rel_type == elfcpp::SHT_RELA)
     {
-      r_offset = rela->get_r_offset();
-      r_info = rela->get_r_info();
-      r_addend = rela->get_r_addend();
+      const elfcpp::Rela<size, big_endian> rela(preloc);
+      r_offset = rela.get_r_offset();
+      r_info = rela.get_r_info();
+      r_addend = rela.get_r_addend();
     }
   else
     {
-      r_offset = rel->get_r_offset();
-      r_info = rel->get_r_info();
+      const elfcpp::Rel<size, big_endian> rel(preloc);
+      r_offset = rel.get_r_offset();
+      r_info = rel.get_r_info();
       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;
@@ -10188,68 +10160,6 @@ Target_mips<size, big_endian>::Relocate::relocate(
   return true;
 }
 
-template<int size, bool big_endian>
-inline bool
-Target_mips<size, big_endian>::Relocate::relocate(
-                        const Relocate_info<size, big_endian>* relinfo,
-                        Target_mips* target,
-                        Output_section* output_section,
-                        size_t relnum,
-                        const elfcpp::Rela<size, big_endian>& reloc,
-                        unsigned int r_type,
-                        const Sized_symbol<size>* gsym,
-                        const Symbol_value<size>* psymval,
-                        unsigned char* view,
-                        Mips_address address,
-                        section_size_type view_size)
-{
-  return relocate(
-    relinfo,
-    target,
-    output_section,
-    relnum,
-    &reloc,
-    (const elfcpp::Rel<size, big_endian>*) NULL,
-    elfcpp::SHT_RELA,
-    r_type,
-    gsym,
-    psymval,
-    view,
-    address,
-    view_size);
-}
-
-template<int size, bool big_endian>
-inline bool
-Target_mips<size, big_endian>::Relocate::relocate(
-                        const Relocate_info<size, big_endian>* relinfo,
-                        Target_mips* target,
-                        Output_section* output_section,
-                        size_t relnum,
-                        const elfcpp::Rel<size, big_endian>& reloc,
-                        unsigned int r_type,
-                        const Sized_symbol<size>* gsym,
-                        const Symbol_value<size>* psymval,
-                        unsigned char* view,
-                        Mips_address address,
-                        section_size_type view_size)
-{
-  return relocate(
-    relinfo,
-    target,
-    output_section,
-    relnum,
-    (const elfcpp::Rela<size, big_endian>*) NULL,
-    &reloc,
-    elfcpp::SHT_REL,
-    r_type,
-    gsym,
-    psymval,
-    view,
-    address,
-    view_size);
-}
-
 // Get the Reference_flags for a particular relocation.
 
 template<int size, bool big_endian>
index c2bef90567523ebdc296ab3bde62b0bf1a6cfee1..f408408d28a793ce3d736a35552ade9c5f4add30 100644 (file)
@@ -2944,6 +2944,8 @@ struct Relocate_info
   unsigned int reloc_shndx;
   // Section header of relocation section.
   const unsigned char* reloc_shdr;
+  // Info about how relocs should be handled
+  Relocatable_relocs* rr;
   // Section index of section being relocated.
   unsigned int data_shndx;
   // Section header of data section.
index 12215ffe2735b4bd687b3e2980efefb3766cde8e..f16faf7f34a2afff803520eaa45fa58e136ec80f 100644 (file)
@@ -671,7 +671,6 @@ class Target_powerpc : public Sized_target<size, big_endian>
                  Output_section* output_section,
                  typename elfcpp::Elf_types<size>::Elf_Off
                     offset_in_output_section,
-                 const Relocatable_relocs*,
                  unsigned char*,
                  Address view_address,
                  section_size_type,
@@ -1072,13 +1071,10 @@ class Target_powerpc : public Sized_target<size, big_endian>
     // 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>*, Target_powerpc*,
-            Output_section*, size_t relnum,
-            const elfcpp::Rela<size, big_endian>&,
-            unsigned int r_type, const Sized_symbol<size>*,
-            const Symbol_value<size>*,
-            unsigned char*,
-            typename elfcpp::Elf_types<size>::Elf_Addr,
+    relocate(const Relocate_info<size, big_endian>*, unsigned int,
+            Target_powerpc*, Output_section*, size_t, const unsigned char*,
+            const Sized_symbol<size>*, const Symbol_value<size>*,
+            unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr,
             section_size_type);
   };
 
@@ -6998,11 +6994,11 @@ template<int size, bool big_endian>
 inline bool
 Target_powerpc<size, big_endian>::Relocate::relocate(
     const Relocate_info<size, big_endian>* relinfo,
+    unsigned int,
     Target_powerpc* target,
     Output_section* os,
     size_t relnum,
-    const elfcpp::Rela<size, big_endian>& rela,
-    unsigned int r_type,
+    const unsigned char* preloc,
     const Sized_symbol<size>* gsym,
     const Symbol_value<size>* psymval,
     unsigned char* view,
@@ -7012,6 +7008,8 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
   if (view == NULL)
     return true;
 
+  const elfcpp::Rela<size, big_endian> rela(preloc);
+  unsigned int r_type = elfcpp::elf_r_type<size>(rela.get_r_info());
   switch (this->maybe_skip_tls_get_addr_call(r_type, gsym))
     {
     case Track_tls::NOT_EXPECTED:
@@ -8220,7 +8218,6 @@ Target_powerpc<size, big_endian>::relocate_relocs(
     size_t reloc_count,
     Output_section* output_section,
     typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
-    const Relocatable_relocs* rr,
     unsigned char*,
     Address view_address,
     section_size_type,
@@ -8251,7 +8248,7 @@ Target_powerpc<size, big_endian>::relocate_relocs(
   bool zap_next = false;
   for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
     {
-      Relocatable_relocs::Reloc_strategy strategy = rr->strategy(i);
+      Relocatable_relocs::Reloc_strategy strategy = relinfo->rr->strategy(i);
       if (strategy == Relocatable_relocs::RELOC_DISCARD)
        continue;
 
index b0f9b1c01aabd6b9ab9b6cc9fdff83cbff4f4499..f18f43220125065c3c6932f25e1f1adad33f02f8 100644 (file)
@@ -1010,33 +1010,33 @@ Sized_relobj_file<size, big_endian>::do_relocate_sections(
                                     &reloc_map);
        }
 
+      Relocatable_relocs* rr = NULL;
+      if (parameters->options().emit_relocs()
+         || parameters->options().relocatable())
+       rr = this->relocatable_relocs(i);
+      relinfo.rr = rr;
+
       if (!parameters->options().relocatable())
        {
          target->relocate_section(&relinfo, sh_type, prelocs, reloc_count, os,
                                   output_offset == invalid_address,
                                   view, address, view_size, reloc_map);
          if (parameters->options().emit_relocs())
-           {
-             Relocatable_relocs* rr = this->relocatable_relocs(i);
-             target->relocate_relocs(&relinfo, sh_type, prelocs, reloc_count,
-                                     os, output_offset, rr,
-                                     view, address, view_size,
-                                     (*pviews)[i].view,
-                                     (*pviews)[i].view_size);
-           }
+           target->relocate_relocs(&relinfo, sh_type, prelocs, reloc_count,
+                                   os, output_offset,
+                                   view, address, view_size,
+                                   (*pviews)[i].view,
+                                   (*pviews)[i].view_size);
          if (parameters->incremental())
            this->incremental_relocs_write(&relinfo, sh_type, prelocs,
                                           reloc_count, os, output_offset, of);
        }
       else
-       {
-         Relocatable_relocs* rr = this->relocatable_relocs(i);
-         target->relocate_relocs(&relinfo, sh_type, prelocs, reloc_count,
-                                 os, output_offset, rr,
-                                 view, address, view_size,
-                                 (*pviews)[i].view,
-                                 (*pviews)[i].view_size);
-       }
+       target->relocate_relocs(&relinfo, sh_type, prelocs, reloc_count,
+                               os, output_offset,
+                               view, address, view_size,
+                               (*pviews)[i].view,
+                               (*pviews)[i].view_size);
     }
 }
 
index 559206eff7608d4add336defc0dabd63d397a46d..f325ae67c6493f5d487414143e025f9ae0c85ef0 100644 (file)
@@ -296,6 +296,14 @@ class Relocatable_relocs
     return static_cast<Reloc_strategy>(this->reloc_strategies_[i]);
   }
 
+  // Set the strategy for reloc I.
+  void
+  set_strategy(unsigned int i, Reloc_strategy strategy)
+  {
+    gold_assert(i < this->reloc_strategies_.size());
+    this->reloc_strategies_[i] = strategy;
+  }
+
   // Return the number of relocations to create in the output file.
   size_t
   output_reloc_count() const
index e329703c383a1e32ab0dbac66879a180a7799a33..45c0ba70ad43c5b582ff407357ffefdb707762eb 100644 (file)
@@ -361,7 +361,6 @@ class Target_s390 : public Sized_target<size, true>
       size_t reloc_count,
       Output_section* output_section,
       typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
-      const Relocatable_relocs*,
       unsigned char* view,
       typename elfcpp::Elf_types<size>::Elf_Addr view_address,
       section_size_type view_size,
@@ -553,11 +552,9 @@ class Target_s390 : public Sized_target<size, true>
     // Do a relocation.  Return false if the caller should not issue
     // any warnings about this relocation.
     inline bool
-    relocate(const Relocate_info<size, true>*, Target_s390*,
-            Output_section*,
-            size_t relnum, const elfcpp::Rela<size, true>&,
-            unsigned int r_type, const Sized_symbol<size>*,
-            const Symbol_value<size>*,
+    relocate(const Relocate_info<size, true>*, unsigned int,
+            Target_s390*, Output_section*, size_t, const unsigned char*,
+            const Sized_symbol<size>*, const Symbol_value<size>*,
             unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr,
             section_size_type);
 
@@ -3115,11 +3112,11 @@ template<int size>
 inline bool
 Target_s390<size>::Relocate::relocate(
     const Relocate_info<size, true>* relinfo,
+    unsigned int,
     Target_s390<size>* target,
     Output_section*,
     size_t relnum,
-    const elfcpp::Rela<size, true>& rela,
-    unsigned int r_type,
+    const unsigned char* preloc,
     const Sized_symbol<size>* gsym,
     const Symbol_value<size>* psymval,
     unsigned char* view,
@@ -3129,6 +3126,8 @@ Target_s390<size>::Relocate::relocate(
   if (view == NULL)
     return true;
 
+  const elfcpp::Rela<size, true> rela(preloc);
+  unsigned int r_type = elfcpp::elf_r_type<size>(rela.get_r_info());
   const Sized_relobj_file<size, true>* object = relinfo->object;
 
   // Pick the value to use for symbols defined in the PLT.
@@ -4171,7 +4170,6 @@ Target_s390<size>::relocate_relocs(
     size_t reloc_count,
     Output_section* output_section,
     typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
-    const Relocatable_relocs* rr,
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr view_address,
     section_size_type view_size,
@@ -4186,7 +4184,6 @@ Target_s390<size>::relocate_relocs(
     reloc_count,
     output_section,
     offset_in_output_section,
-    rr,
     view,
     view_address,
     view_size,
index 2b11550e098263206a9aabf46f02bf3afcdf382a..27ea5529d3087f34cae7c5eeb68acfde83ab7d3d 100644 (file)
@@ -140,7 +140,6 @@ class Target_sparc : public Sized_target<size, big_endian>
                  Output_section* output_section,
                  typename elfcpp::Elf_types<size>::Elf_Off
                     offset_in_output_section,
-                 const Relocatable_relocs*,
                  unsigned char* view,
                  typename elfcpp::Elf_types<size>::Elf_Addr view_address,
                  section_size_type view_size,
@@ -316,13 +315,10 @@ class Target_sparc : public Sized_target<size, big_endian>
     // 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>*, Target_sparc*,
-            Output_section*, size_t relnum,
-            const elfcpp::Rela<size, big_endian>&,
-            unsigned int r_type, const Sized_symbol<size>*,
-            const Symbol_value<size>*,
-            unsigned char*,
-            typename elfcpp::Elf_types<size>::Elf_Addr,
+    relocate(const Relocate_info<size, big_endian>*, unsigned int,
+            Target_sparc*, Output_section*, size_t, const unsigned char*,
+            const Sized_symbol<size>*, const Symbol_value<size>*,
+            unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr,
             section_size_type);
 
    private:
@@ -3169,17 +3165,19 @@ template<int size, bool big_endian>
 inline bool
 Target_sparc<size, big_endian>::Relocate::relocate(
                        const Relocate_info<size, big_endian>* relinfo,
+                       unsigned int,
                        Target_sparc* target,
                        Output_section*,
                        size_t relnum,
-                       const elfcpp::Rela<size, big_endian>& rela,
-                       unsigned int r_type,
+                       const unsigned char* preloc,
                        const Sized_symbol<size>* gsym,
                        const Symbol_value<size>* psymval,
                        unsigned char* view,
                        typename elfcpp::Elf_types<size>::Elf_Addr address,
                        section_size_type view_size)
 {
+  const elfcpp::Rela<size, big_endian> rela(preloc);
+  unsigned int r_type = elfcpp::elf_r_type<size>(rela.get_r_info());
   bool orig_is_ifunc = psymval->is_ifunc_symbol();
   r_type &= 0xff;
 
@@ -4224,7 +4222,6 @@ Target_sparc<size, big_endian>::relocate_relocs(
     size_t reloc_count,
     Output_section* output_section,
     typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
-    const Relocatable_relocs* rr,
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr view_address,
     section_size_type view_size,
@@ -4239,7 +4236,6 @@ Target_sparc<size, big_endian>::relocate_relocs(
     reloc_count,
     output_section,
     offset_in_output_section,
-    rr,
     view,
     view_address,
     view_size,
index 89906af2b4a5298b04442f138de001ef47893e42..63b884f29e1a7c2926ba06b39965e4021f1b0381 100644 (file)
@@ -297,7 +297,6 @@ relocate_section(
 
       typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info();
       unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
-      unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
 
       const Sized_symbol<size>* sym;
 
@@ -400,9 +399,9 @@ relocate_section(
       if (offset < 0 || static_cast<section_size_type>(offset) >= view_size)
        v = NULL;
 
-      if (!relocate.relocate(relinfo, target, output_section, i, reloc,
-                            r_type, sym, psymval, v, view_address + offset,
-                            view_size))
+      if (!relocate.relocate(relinfo, sh_type, target, output_section,
+                            i, prelocs, sym, psymval,
+                            v, view_address + offset, view_size))
        continue;
 
       if (v == NULL)
@@ -443,7 +442,6 @@ apply_relocation(const Relocate_info<size, big_endian>* relinfo,
   // Construct the ELF relocation in a temporary buffer.
   const int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
   unsigned char relbuf[reloc_size];
-  elfcpp::Rela<size, big_endian> rel(relbuf);
   elfcpp::Rela_write<size, big_endian> orel(relbuf);
   orel.put_r_offset(r_offset);
   orel.put_r_info(elfcpp::elf_r_info<size>(0, r_type));
@@ -461,7 +459,8 @@ apply_relocation(const Relocate_info<size, big_endian>* relinfo,
     symval.set_is_ifunc_symbol();
 
   Relocate relocate;
-  relocate.relocate(relinfo, target, NULL, -1U, rel, r_type, sym, &symval,
+  relocate.relocate(relinfo, elfcpp::SHT_RELA, target, NULL,
+                   -1U, relbuf, sym, &symval,
                    view + r_offset, address + r_offset, view_size);
 }
 
@@ -619,7 +618,6 @@ relocate_relocs(
     size_t reloc_count,
     Output_section* output_section,
     typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
-    const Relocatable_relocs* rr,
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr view_address,
     section_size_type view_size,
@@ -640,7 +638,7 @@ relocate_relocs(
 
   for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
     {
-      Relocatable_relocs::Reloc_strategy strategy = rr->strategy(i);
+      Relocatable_relocs::Reloc_strategy strategy = relinfo->rr->strategy(i);
       if (strategy == Relocatable_relocs::RELOC_DISCARD)
        continue;
 
index b21c56a479528c921bb48e7baf34214fdfe8a70d..6e08f381a961903bde2de1f8902fa1c824aa08c1 100644 (file)
@@ -934,7 +934,6 @@ class Sized_target : public Target
                  Output_section* output_section,
                  typename elfcpp::Elf_types<size>::Elf_Off
                     offset_in_output_section,
-                 const Relocatable_relocs*,
                  unsigned char* view,
                  typename elfcpp::Elf_types<size>::Elf_Addr view_address,
                  section_size_type view_size,
index 2e7f40c57b9b57af848bee584c053327fae6c160..c47a27bae99667118a57306583e9d44ff948c1b0 100644 (file)
@@ -75,7 +75,7 @@ class Target_test : public Sized_target<size, big_endian>
   relocate_relocs(const Relocate_info<size, big_endian>*,
                  unsigned int, const unsigned char*, size_t,
                  Output_section*, typename elfcpp::Elf_types<size>::Elf_Off,
-                  const Relocatable_relocs*, unsigned char*,
+                 unsigned char*,
                  typename elfcpp::Elf_types<size>::Elf_Addr,
                  section_size_type, unsigned char*,
                  section_size_type)
index b74c8c749d72006482e722e1abf08a5e342bae0c..7d363a263e5a2b8904d814960e386ec1efd70910 100644 (file)
@@ -317,7 +317,6 @@ class Target_tilegx : public Sized_target<size, big_endian>
       size_t reloc_count,
       Output_section* output_section,
       typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
-      const Relocatable_relocs*,
       unsigned char* view,
       typename elfcpp::Elf_types<size>::Elf_Addr view_address,
       section_size_type view_size,
@@ -517,13 +516,11 @@ class Target_tilegx : public Sized_target<size, big_endian>
     // 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>*, Target_tilegx*,
-             Output_section*,
-             size_t relnum, const elfcpp::Rela<size, big_endian>&,
-             unsigned int r_type, const Sized_symbol<size>*,
-             const Symbol_value<size>*,
-             unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr,
-             section_size_type);
+    relocate(const Relocate_info<size, big_endian>*, unsigned int,
+            Target_tilegx*, Output_section*, size_t, const unsigned char*,
+            const Sized_symbol<size>*, const Symbol_value<size>*,
+            unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr,
+            section_size_type);
   };
 
   // A class which returns the size required for a relocation type,
@@ -4327,11 +4324,11 @@ template<int size, bool big_endian>
 inline bool
 Target_tilegx<size, big_endian>::Relocate::relocate(
     const Relocate_info<size, big_endian>* relinfo,
+    unsigned int,
     Target_tilegx<size, big_endian>* target,
     Output_section*,
     size_t relnum,
-    const elfcpp::Rela<size, big_endian>& rela,
-    unsigned int r_type,
+    const unsigned char* preloc,
     const Sized_symbol<size>* gsym,
     const Symbol_value<size>* psymval,
     unsigned char* view,
@@ -4344,6 +4341,8 @@ Target_tilegx<size, big_endian>::Relocate::relocate(
   typedef Tilegx_relocate_functions<size, big_endian> TilegxReloc;
   typename TilegxReloc::Tilegx_howto r_howto;
 
+  const elfcpp::Rela<size, big_endian> rela(preloc);
+  unsigned int r_type = elfcpp::elf_r_type<size>(rela.get_r_info());
   const Sized_relobj_file<size, big_endian>* object = relinfo->object;
 
   // Pick the value to use for symbols defined in the PLT.
@@ -4851,7 +4850,6 @@ Target_tilegx<size, big_endian>::relocate_relocs(
     size_t reloc_count,
     Output_section* output_section,
     typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
-    const Relocatable_relocs* rr,
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr view_address,
     section_size_type view_size,
@@ -4866,7 +4864,6 @@ Target_tilegx<size, big_endian>::relocate_relocs(
     reloc_count,
     output_section,
     offset_in_output_section,
-    rr,
     view,
     view_address,
     view_size,
index 503a677a00ef10f408c510d0db4d5b27609631b4..12c65524b757a5ab33f04162b72323358e0eea2f 100644 (file)
@@ -505,7 +505,6 @@ class Target_x86_64 : public Sized_target<size, false>
       size_t reloc_count,
       Output_section* output_section,
       typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
-      const Relocatable_relocs*,
       unsigned char* view,
       typename elfcpp::Elf_types<size>::Elf_Addr view_address,
       section_size_type view_size,
@@ -782,11 +781,9 @@ class Target_x86_64 : public Sized_target<size, false>
     // Do a relocation.  Return false if the caller should not issue
     // any warnings about this relocation.
     inline bool
-    relocate(const Relocate_info<size, false>*, Target_x86_64*,
-            Output_section*,
-            size_t relnum, const elfcpp::Rela<size, false>&,
-            unsigned int r_type, const Sized_symbol<size>*,
-            const Symbol_value<size>*,
+    relocate(const Relocate_info<size, false>*, unsigned int,
+            Target_x86_64*, Output_section*, size_t, const unsigned char*,
+            const Sized_symbol<size>*, const Symbol_value<size>*,
             unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr,
             section_size_type);
 
@@ -3348,17 +3345,20 @@ template<int size>
 inline bool
 Target_x86_64<size>::Relocate::relocate(
     const Relocate_info<size, false>* relinfo,
+    unsigned int,
     Target_x86_64<size>* target,
     Output_section*,
     size_t relnum,
-    const elfcpp::Rela<size, false>& rela,
-    unsigned int r_type,
+    const unsigned char* preloc,
     const Sized_symbol<size>* gsym,
     const Symbol_value<size>* psymval,
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr address,
     section_size_type view_size)
 {
+  const elfcpp::Rela<size, false> rela(preloc);
+  unsigned int r_type = elfcpp::elf_r_type<size>(rela.get_r_info());
+
   if (this->skip_call_tls_get_addr_)
     {
       if ((r_type != elfcpp::R_X86_64_PLT32
@@ -4436,7 +4436,6 @@ Target_x86_64<size>::relocate_relocs(
     size_t reloc_count,
     Output_section* output_section,
     typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
-    const Relocatable_relocs* rr,
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr view_address,
     section_size_type view_size,
@@ -4451,7 +4450,6 @@ Target_x86_64<size>::relocate_relocs(
     reloc_count,
     output_section,
     offset_in_output_section,
-    rr,
     view,
     view_address,
     view_size,