[GOLD] Add more params to relocate() and relocate_section()

Alan Modra amodra@gmail.com
Wed Nov 25 01:35:00 GMT 2015


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* parameter to mark edited relocs.

This patch adds the infrastructure without making use of it.

Note that relocate() may be called with both of the new params NULL,
when called from apply_relocation() for incremental relocation.

OK to apply?

	* powerpc.cc (relocate_section): Add Relocatable_relocs* parameter.
	(relocate): Add raw relocs and Relocatable_relocs* parameter.
	* aarch64.cc: Likewise.
	* arm.cc: Likewise.
	* i386.cc: Likewise.
	* mips.cc: Likewise.
	* reloc.cc: Likewise.
	* reloc.h: Likewise.
	* s390.cc: Likewise.
	* sparc.cc: Likewise.
	* target-reloc.h: Likewise.
	* target.h: Likewise.
	* tilegx.cc: Likewise.
	* x86_64.cc: Likewise.
	* testsuite/testfile.cc: Likewise.
	* reloc.h (Relocatable_relocs::set_strategy): New accessor.

diff --git a/gold/aarch64.cc b/gold/aarch64.cc
index 5ca5e0a..a4621d1 100644
--- a/gold/aarch64.cc
+++ b/gold/aarch64.cc
@@ -2852,7 +2852,8 @@ class Target_aarch64 : public Sized_target<size, big_endian>
 		   unsigned char* view,
 		   typename elfcpp::Elf_types<size>::Elf_Addr view_address,
 		   section_size_type view_size,
-		   const Reloc_symbol_changes*);
+		   const Reloc_symbol_changes*,
+		   Relocatable_relocs*);
 
   // Scan the relocs during a relocatable link.
   void
@@ -3158,12 +3159,13 @@ class Target_aarch64 : public Sized_target<size, big_endian>
     // 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>&,
+	     Output_section*, size_t, const unsigned char*,
+	     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);
+	     section_size_type,
+	     Relocatable_relocs*);
 
   private:
     inline typename AArch64_relocate_functions<size, big_endian>::Status
@@ -6815,13 +6817,15 @@ Target_aarch64<size, big_endian>::Relocate::relocate(
     Target_aarch64<size, big_endian>* target,
     Output_section* ,
     size_t relnum,
+    const unsigned char*,
     const elfcpp::Rela<size, big_endian>& rela,
     unsigned int r_type,
     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 */)
+    section_size_type /* view_size */,
+    Relocatable_relocs* /* rr */)
 {
   if (view == NULL)
     return true;
@@ -7867,7 +7871,8 @@ Target_aarch64<size, big_endian>::relocate_section(
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr address,
     section_size_type view_size,
-    const Reloc_symbol_changes* reloc_symbol_changes)
+    const Reloc_symbol_changes* reloc_symbol_changes,
+    Relocatable_relocs* rr)
 {
   gold_assert(sh_type == elfcpp::SHT_RELA);
   typedef typename Target_aarch64<size, big_endian>::Relocate AArch64_relocate;
@@ -7882,7 +7887,8 @@ Target_aarch64<size, big_endian>::relocate_section(
     view,
     address,
     view_size,
-    reloc_symbol_changes);
+    reloc_symbol_changes,
+    rr);
 }
 
 // Return the size of a relocation while scanning during a relocatable
diff --git a/gold/arm.cc b/gold/arm.cc
index 4a6d414..9f0e8f2 100644
--- a/gold/arm.cc
+++ b/gold/arm.cc
@@ -2281,7 +2281,8 @@ class Target_arm : public Sized_target<32, big_endian>
 		   unsigned char* view,
 		   Arm_address view_address,
 		   section_size_type view_size,
-		   const Reloc_symbol_changes*);
+		   const Reloc_symbol_changes*,
+		   Relocatable_relocs*);
 
   // Scan the relocs during a relocatable link.
   void
@@ -2670,12 +2671,13 @@ class Target_arm : public Sized_target<32, big_endian>
     // any warnings about this relocation.
     inline bool
     relocate(const Relocate_info<32, big_endian>*, Target_arm*,
-	     Output_section*,  size_t relnum,
+	     Output_section*, size_t, const unsigned char*,
 	     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);
+	     section_size_type,
+	     Relocatable_relocs*);
 
     // Return whether we want to pass flag NON_PIC_REF for this
     // reloc.  This means the relocation type accesses a symbol not via
@@ -9326,13 +9328,15 @@ Target_arm<big_endian>::Relocate::relocate(
     Target_arm* target,
     Output_section* output_section,
     size_t relnum,
+    const unsigned char*,
     const elfcpp::Rel<32, big_endian>& rel,
     unsigned int r_type,
     const Sized_symbol<32>* gsym,
     const Symbol_value<32>* psymval,
     unsigned char* view,
     Arm_address address,
-    section_size_type view_size)
+    section_size_type view_size,
+    Relocatable_relocs*)
 {
   if (view == NULL)
     return true;
@@ -9998,7 +10002,8 @@ Target_arm<big_endian>::relocate_section(
     unsigned char* view,
     Arm_address address,
     section_size_type view_size,
-    const Reloc_symbol_changes* reloc_symbol_changes)
+    const Reloc_symbol_changes* reloc_symbol_changes,
+    Relocatable_relocs* rr)
 {
   typedef typename Target_arm<big_endian>::Relocate Arm_relocate;
   gold_assert(sh_type == elfcpp::SHT_REL);
@@ -10037,7 +10042,8 @@ Target_arm<big_endian>::relocate_section(
     view,
     address,
     view_size,
-    reloc_symbol_changes);
+    reloc_symbol_changes,
+    rr);
 }
 
 // Return the size of a relocation while scanning during a relocatable
@@ -12285,9 +12291,9 @@ Target_arm<big_endian>::relocate_stub(
       elfcpp::Rel<32, big_endian> rel(reloc_buffer);
 
       relocate.relocate(relinfo, this, output_section,
-			this->fake_relnum_for_stubs, rel, r_type,
+			this->fake_relnum_for_stubs, NULL, rel, r_type,
 			NULL, &symval, view + reloc_offset,
-			address + reloc_offset, reloc_size);
+			address + reloc_offset, reloc_size, NULL);
     }
 }
 
diff --git a/gold/i386.cc b/gold/i386.cc
index 4f41be4..5142731 100644
--- a/gold/i386.cc
+++ b/gold/i386.cc
@@ -412,7 +412,8 @@ class Target_i386 : public Sized_target<32, false>
 		   unsigned char* view,
 		   elfcpp::Elf_types<32>::Elf_Addr view_address,
 		   section_size_type view_size,
-		   const Reloc_symbol_changes*);
+		   const Reloc_symbol_changes*,
+		   Relocatable_relocs*);
 
   // Scan the relocs during a relocatable link.
   void
@@ -635,11 +636,12 @@ class Target_i386 : public Sized_target<32, false>
     // 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>&,
+	     size_t, const unsigned char*, const elfcpp::Rel<32, false>&,
 	     unsigned int r_type, const Sized_symbol<32>*,
 	     const Symbol_value<32>*,
 	     unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
-	     section_size_type);
+	     section_size_type,
+	     Relocatable_relocs*);
 
    private:
     // Do a TLS relocation.
@@ -2732,16 +2734,18 @@ 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)
+				Target_i386* target,
+				Output_section* output_section,
+				size_t relnum,
+				const unsigned char*,
+				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,
+				Relocatable_relocs*)
 {
   if (this->skip_call_tls_get_addr_)
     {
@@ -3603,7 +3607,8 @@ Target_i386::relocate_section(const Relocate_info<32, false>* relinfo,
 			      unsigned char* view,
 			      elfcpp::Elf_types<32>::Elf_Addr address,
 			      section_size_type view_size,
-			      const Reloc_symbol_changes* reloc_symbol_changes)
+			      const Reloc_symbol_changes* reloc_symbol_changes,
+			      Relocatable_relocs* rr)
 {
   gold_assert(sh_type == elfcpp::SHT_REL);
 
@@ -3618,7 +3623,8 @@ Target_i386::relocate_section(const Relocate_info<32, false>* relinfo,
     view,
     address,
     view_size,
-    reloc_symbol_changes);
+    reloc_symbol_changes,
+    rr);
 }
 
 // Return the size of a relocation while scanning during a relocatable
diff --git a/gold/mips.cc b/gold/mips.cc
index 051d49a..a85e791 100644
--- a/gold/mips.cc
+++ b/gold/mips.cc
@@ -2938,7 +2938,8 @@ class Target_mips : public Sized_target<size, big_endian>
                    unsigned char* view,
                    Mips_address view_address,
                    section_size_type view_size,
-                   const Reloc_symbol_changes*);
+                   const Reloc_symbol_changes*,
+                   Relocatable_relocs*);
 
   // Scan the relocs during a relocatable link.
   void
@@ -3393,7 +3394,7 @@ class Target_mips : public Sized_target<size, big_endian>
     // any warnings about this relocation.
     inline bool
     relocate(const Relocate_info<size, big_endian>*, Target_mips*,
-             Output_section*, size_t relnum,
+             Output_section*, size_t, const unsigned char*,
              const elfcpp::Rela<size, big_endian>*,
              const elfcpp::Rel<size, big_endian>*,
              unsigned int,
@@ -3401,27 +3402,30 @@ class Target_mips : public Sized_target<size, big_endian>
              const Symbol_value<size>*,
              unsigned char*,
              Mips_address,
-             section_size_type);
+             section_size_type,
+             Relocatable_relocs*);
 
     inline bool
     relocate(const Relocate_info<size, big_endian>*, Target_mips*,
-             Output_section*, size_t relnum,
+             Output_section*, size_t, const unsigned char*,
              const elfcpp::Rel<size, big_endian>&,
              unsigned int, const Sized_symbol<size>*,
              const Symbol_value<size>*,
              unsigned char*,
              Mips_address,
-             section_size_type);
+             section_size_type,
+             Relocatable_relocs*);
 
     inline bool
     relocate(const Relocate_info<size, big_endian>*, Target_mips*,
-             Output_section*, size_t relnum,
+             Output_section*, size_t, const unsigned char*,
              const elfcpp::Rela<size, big_endian>&,
              unsigned int, const Sized_symbol<size>*,
              const Symbol_value<size>*,
              unsigned char*,
              Mips_address,
-             section_size_type);
+             section_size_type,
+             Relocatable_relocs*);
   };
 
   // A class which returns the size required for a relocation type,
@@ -8248,7 +8252,8 @@ Target_mips<size, big_endian>::relocate_section(
                         unsigned char* view,
                         Mips_address address,
                         section_size_type view_size,
-                        const Reloc_symbol_changes* reloc_symbol_changes)
+                        const Reloc_symbol_changes* reloc_symbol_changes,
+                        Relocatable_relocs* rr)
 {
   typedef Target_mips<size, big_endian> Mips;
   typedef typename Target_mips<size, big_endian>::Relocate Mips_relocate;
@@ -8265,7 +8270,8 @@ Target_mips<size, big_endian>::relocate_section(
       view,
       address,
       view_size,
-      reloc_symbol_changes);
+      reloc_symbol_changes,
+      rr);
   else if (sh_type == elfcpp::SHT_RELA)
     gold::relocate_section<size, big_endian, Mips, elfcpp::SHT_RELA,
       Mips_relocate, gold::Default_comdat_behavior>(
@@ -8278,7 +8284,8 @@ Target_mips<size, big_endian>::relocate_section(
       view,
       address,
       view_size,
-     reloc_symbol_changes);
+      reloc_symbol_changes,
+      rr);
 }
 
 // Return the size of a relocation while scanning during a relocatable
@@ -9566,6 +9573,7 @@ Target_mips<size, big_endian>::Relocate::relocate(
                         Target_mips* target,
                         Output_section* output_section,
                         size_t relnum,
+                        const unsigned char*,
                         const elfcpp::Rela<size, big_endian>* rela,
                         const elfcpp::Rel<size, big_endian>* rel,
                         unsigned int rel_type,
@@ -9574,7 +9582,8 @@ Target_mips<size, big_endian>::Relocate::relocate(
                         const Symbol_value<size>* psymval,
                         unsigned char* view,
                         Mips_address address,
-                        section_size_type)
+                        section_size_type,
+                        Relocatable_relocs*)
 {
   Mips_address r_offset;
   typename elfcpp::Elf_types<size>::Elf_WXword r_info;
@@ -10195,19 +10204,22 @@ Target_mips<size, big_endian>::Relocate::relocate(
                         Target_mips* target,
                         Output_section* output_section,
                         size_t relnum,
+                        const unsigned char* preloc,
                         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)
+                        section_size_type view_size,
+                        Relocatable_relocs* rr)
 {
   return relocate(
     relinfo,
     target,
     output_section,
     relnum,
+    preloc,
     &reloc,
     (const elfcpp::Rel<size, big_endian>*) NULL,
     elfcpp::SHT_RELA,
@@ -10216,7 +10228,8 @@ Target_mips<size, big_endian>::Relocate::relocate(
     psymval,
     view,
     address,
-    view_size);
+    view_size,
+    rr);
 }
 
 template<int size, bool big_endian>
@@ -10226,19 +10239,22 @@ Target_mips<size, big_endian>::Relocate::relocate(
                         Target_mips* target,
                         Output_section* output_section,
                         size_t relnum,
+                        const unsigned char* preloc,
                         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)
+                        section_size_type view_size,
+                        Relocatable_relocs* rr)
 {
   return relocate(
     relinfo,
     target,
     output_section,
     relnum,
+    preloc,
     (const elfcpp::Rela<size, big_endian>*) NULL,
     &reloc,
     elfcpp::SHT_REL,
@@ -10247,7 +10263,8 @@ Target_mips<size, big_endian>::Relocate::relocate(
     psymval,
     view,
     address,
-    view_size);
+    view_size,
+    rr);
 }
 
 // Get the Reference_flags for a particular relocation.
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index 5441c52..c1a6213 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -645,7 +645,8 @@ class Target_powerpc : public Sized_target<size, big_endian>
 		   unsigned char* view,
 		   Address view_address,
 		   section_size_type view_size,
-		   const Reloc_symbol_changes*);
+		   const Reloc_symbol_changes*,
+		   Relocatable_relocs* rr);
 
   // Scan the relocs during a relocatable link.
   void
@@ -1073,13 +1074,14 @@ class Target_powerpc : public Sized_target<size, big_endian>
     // any warnings about this relocation.
     inline bool
     relocate(const Relocate_info<size, big_endian>*, Target_powerpc*,
-	     Output_section*, size_t relnum,
+	     Output_section*, size_t, const unsigned char*,
 	     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);
+	     section_size_type,
+	     Relocatable_relocs*);
   };
 
   class Relocate_comdat_behavior
@@ -6993,13 +6995,15 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
     Target_powerpc* target,
     Output_section* os,
     size_t relnum,
+    const unsigned char*,
     const elfcpp::Rela<size, big_endian>& rela,
     unsigned int r_type,
     const Sized_symbol<size>* gsym,
     const Symbol_value<size>* psymval,
     unsigned char* view,
     Address address,
-    section_size_type view_size)
+    section_size_type view_size,
+    Relocatable_relocs*)
 {
   if (view == NULL)
     return true;
@@ -8065,7 +8069,8 @@ Target_powerpc<size, big_endian>::relocate_section(
     unsigned char* view,
     Address address,
     section_size_type view_size,
-    const Reloc_symbol_changes* reloc_symbol_changes)
+    const Reloc_symbol_changes* reloc_symbol_changes,
+    Relocatable_relocs* rr)
 {
   typedef Target_powerpc<size, big_endian> Powerpc;
   typedef typename Target_powerpc<size, big_endian>::Relocate Powerpc_relocate;
@@ -8085,7 +8090,8 @@ Target_powerpc<size, big_endian>::relocate_section(
     view,
     address,
     view_size,
-    reloc_symbol_changes);
+    reloc_symbol_changes,
+    rr);
 }
 
 class Powerpc_scan_relocatable_reloc
diff --git a/gold/reloc.cc b/gold/reloc.cc
index b0f9b1c..e127044 100644
--- a/gold/reloc.cc
+++ b/gold/reloc.cc
@@ -1012,12 +1012,14 @@ Sized_relobj_file<size, big_endian>::do_relocate_sections(
 
       if (!parameters->options().relocatable())
 	{
+	  Relocatable_relocs* rr = NULL;
+	  if (parameters->options().emit_relocs())
+	    rr = this->relocatable_relocs(i);
 	  target->relocate_section(&relinfo, sh_type, prelocs, reloc_count, os,
 				   output_offset == invalid_address,
-				   view, address, view_size, reloc_map);
+				   view, address, view_size, reloc_map, rr);
 	  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,
diff --git a/gold/reloc.h b/gold/reloc.h
index 559206e..f325ae6 100644
--- a/gold/reloc.h
+++ b/gold/reloc.h
@@ -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
diff --git a/gold/s390.cc b/gold/s390.cc
index e329703..ce0ad6e 100644
--- a/gold/s390.cc
+++ b/gold/s390.cc
@@ -331,7 +331,8 @@ class Target_s390 : public Sized_target<size, true>
 		   unsigned char* view,
 		   typename elfcpp::Elf_types<size>::Elf_Addr view_address,
 		   section_size_type view_size,
-		   const Reloc_symbol_changes*);
+		   const Reloc_symbol_changes*,
+		   Relocatable_relocs*);
 
   // Scan the relocs during a relocatable link.
   void
@@ -554,12 +555,13 @@ class Target_s390 : public Sized_target<size, true>
     // 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>&,
+	     Output_section*, size_t, const unsigned char*,
+	     const elfcpp::Rela<size, true>&,
 	     unsigned int r_type, const Sized_symbol<size>*,
 	     const Symbol_value<size>*,
 	     unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr,
-	     section_size_type);
+	     section_size_type,
+	     Relocatable_relocs*);
 
    private:
     // Do a TLS relocation.
@@ -3118,13 +3120,15 @@ Target_s390<size>::Relocate::relocate(
     Target_s390<size>* target,
     Output_section*,
     size_t relnum,
+    const unsigned char*,
     const elfcpp::Rela<size, true>& rela,
     unsigned int r_type,
     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)
+    section_size_type view_size,
+    Relocatable_relocs*)
 {
   if (view == NULL)
     return true;
@@ -4260,7 +4264,8 @@ Target_s390<size>::relocate_section(
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr address,
     section_size_type view_size,
-    const Reloc_symbol_changes* reloc_symbol_changes)
+    const Reloc_symbol_changes* reloc_symbol_changes,
+    Relocatable_relocs* rr)
 {
   gold_assert(sh_type == elfcpp::SHT_RELA);
 
@@ -4276,7 +4281,8 @@ Target_s390<size>::relocate_section(
     view,
     address,
     view_size,
-    reloc_symbol_changes);
+    reloc_symbol_changes,
+    rr);
 }
 
 // Apply an incremental relocation.  Incremental relocations always refer
diff --git a/gold/sparc.cc b/gold/sparc.cc
index 2b11550..2f5891b 100644
--- a/gold/sparc.cc
+++ b/gold/sparc.cc
@@ -114,7 +114,8 @@ class Target_sparc : public Sized_target<size, big_endian>
 		   unsigned char* view,
 		   typename elfcpp::Elf_types<size>::Elf_Addr view_address,
 		   section_size_type view_size,
-		   const Reloc_symbol_changes*);
+		   const Reloc_symbol_changes*,
+		   Relocatable_relocs*);
 
   // Scan the relocs during a relocatable link.
   void
@@ -317,13 +318,14 @@ class Target_sparc : public Sized_target<size, big_endian>
     // any warnings about this relocation.
     inline bool
     relocate(const Relocate_info<size, big_endian>*, Target_sparc*,
-	     Output_section*, size_t relnum,
+	     Output_section*, size_t, const unsigned char*,
 	     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);
+	     section_size_type,
+	     Relocatable_relocs*);
 
    private:
     // Do a TLS relocation.
@@ -3172,13 +3174,15 @@ Target_sparc<size, big_endian>::Relocate::relocate(
 			Target_sparc* target,
 			Output_section*,
 			size_t relnum,
+			const unsigned char*,
 			const elfcpp::Rela<size, big_endian>& rela,
 			unsigned int r_type,
 			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)
+			section_size_type view_size,
+			Relocatable_relocs*)
 {
   bool orig_is_ifunc = psymval->is_ifunc_symbol();
   r_type &= 0xff;
@@ -4140,7 +4144,8 @@ Target_sparc<size, big_endian>::relocate_section(
 			unsigned char* view,
 			typename elfcpp::Elf_types<size>::Elf_Addr address,
 			section_size_type view_size,
-			const Reloc_symbol_changes* reloc_symbol_changes)
+			const Reloc_symbol_changes* reloc_symbol_changes,
+			Relocatable_relocs* rr)
 {
   typedef Target_sparc<size, big_endian> Sparc;
   typedef typename Target_sparc<size, big_endian>::Relocate Sparc_relocate;
@@ -4158,7 +4163,8 @@ Target_sparc<size, big_endian>::relocate_section(
     view,
     address,
     view_size,
-    reloc_symbol_changes);
+    reloc_symbol_changes,
+    rr);
 }
 
 // Return the size of a relocation while scanning during a relocatable
diff --git a/gold/target-reloc.h b/gold/target-reloc.h
index 89906af..f6d72a3 100644
--- a/gold/target-reloc.h
+++ b/gold/target-reloc.h
@@ -253,6 +253,9 @@ issue_undefined_symbol_error(const Symbol* sym)
 // symbol for the relocation, ignoring the symbol index in the
 // relocation.
 
+// RR allows information about edited code/relocs to be passed to
+// relocate_relocs.  It is NULL when --emit-relocs is not in force.
+
 template<int size, bool big_endian, typename Target_type, int sh_type,
 	 typename Relocate,
 	 typename Relocate_comdat_behavior>
@@ -267,7 +270,8 @@ relocate_section(
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr view_address,
     section_size_type view_size,
-    const Reloc_symbol_changes* reloc_symbol_changes)
+    const Reloc_symbol_changes* reloc_symbol_changes,
+    Relocatable_relocs* rr)
 {
   typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype;
   const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size;
@@ -400,9 +404,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,
+      if (!relocate.relocate(relinfo, target, output_section, i, prelocs, reloc,
 			     r_type, sym, psymval, v, view_address + offset,
-			     view_size))
+			     view_size, rr))
 	continue;
 
       if (v == NULL)
@@ -461,8 +465,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,
-		    view + r_offset, address + r_offset, view_size);
+  relocate.relocate(relinfo, target, NULL, -1U, NULL, rel, r_type, sym, &symval,
+		    view + r_offset, address + r_offset, view_size, NULL);
 }
 
 // This class may be used as a typical class for the
diff --git a/gold/target.h b/gold/target.h
index b21c56a..2338bec 100644
--- a/gold/target.h
+++ b/gold/target.h
@@ -894,6 +894,8 @@ class Sized_target : public Target
   // view.  If NEEDS_SPECIAL_OFFSET_HANDLING is true, the VIEW_xx
   // parameters refer to the complete output section data, not just
   // the input section data.
+  // The Relocatable_relocs parameter allows information to be passed
+  // to relocate_relocs.  It is NULL when --emit-relocs is not in force.
   virtual void
   relocate_section(const Relocate_info<size, big_endian>*,
 		   unsigned int sh_type,
@@ -904,7 +906,8 @@ class Sized_target : public Target
 		   unsigned char* view,
 		   typename elfcpp::Elf_types<size>::Elf_Addr view_address,
 		   section_size_type view_size,
-		   const Reloc_symbol_changes*) = 0;
+		   const Reloc_symbol_changes*,
+		   Relocatable_relocs*) = 0;
 
   // Scan the relocs during a relocatable link.  The parameters are
   // like scan_relocs, with an additional Relocatable_relocs
diff --git a/gold/testsuite/testfile.cc b/gold/testsuite/testfile.cc
index 2e7f40c..0029561 100644
--- a/gold/testsuite/testfile.cc
+++ b/gold/testsuite/testfile.cc
@@ -60,7 +60,8 @@ class Target_test : public Sized_target<size, big_endian>
   relocate_section(const Relocate_info<size, big_endian>*, unsigned int,
 		   const unsigned char*, size_t, Output_section*, bool,
 		   unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr,
-		   section_size_type, const Reloc_symbol_changes*)
+		   section_size_type, const Reloc_symbol_changes*,
+		   Relocatable_relocs*)
   { ERROR("call to Target_test::relocate_section"); }
 
   void
diff --git a/gold/tilegx.cc b/gold/tilegx.cc
index b74c8c7..ae6110e 100644
--- a/gold/tilegx.cc
+++ b/gold/tilegx.cc
@@ -291,7 +291,8 @@ class Target_tilegx : public Sized_target<size, big_endian>
                    unsigned char* view,
                    typename elfcpp::Elf_types<size>::Elf_Addr view_address,
                    section_size_type view_size,
-                   const Reloc_symbol_changes*);
+                   const Reloc_symbol_changes*,
+                   Relocatable_relocs*);
 
   // Scan the relocs during a relocatable link.
   void
@@ -518,12 +519,13 @@ class Target_tilegx : public Sized_target<size, big_endian>
     // 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>&,
+             Output_section*, size_t, const unsigned char*,
+             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);
+             section_size_type,
+             Relocatable_relocs*);
   };
 
   // A class which returns the size required for a relocation type,
@@ -4330,13 +4332,15 @@ Target_tilegx<size, big_endian>::Relocate::relocate(
     Target_tilegx<size, big_endian>* target,
     Output_section*,
     size_t relnum,
+    const unsigned char*,
     const elfcpp::Rela<size, big_endian>& rela,
     unsigned int r_type,
     const Sized_symbol<size>* gsym,
     const Symbol_value<size>* psymval,
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr address,
-    section_size_type)
+    section_size_type,
+    Relocatable_relocs*)
 {
   if (view == NULL)
     return true;
@@ -4740,7 +4744,8 @@ Target_tilegx<size, big_endian>::relocate_section(
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr address,
     section_size_type view_size,
-    const Reloc_symbol_changes* reloc_symbol_changes)
+    const Reloc_symbol_changes* reloc_symbol_changes,
+    Relocatable_relocs* rr)
 {
   typedef Target_tilegx<size, big_endian> Tilegx;
   typedef typename Target_tilegx<size, big_endian>::Relocate Tilegx_relocate;
@@ -4758,7 +4763,8 @@ Target_tilegx<size, big_endian>::relocate_section(
     view,
     address,
     view_size,
-    reloc_symbol_changes);
+    reloc_symbol_changes,
+    rr);
 }
 
 // Apply an incremental relocation.  Incremental relocations always refer
diff --git a/gold/x86_64.cc b/gold/x86_64.cc
index 503a677..71f2008 100644
--- a/gold/x86_64.cc
+++ b/gold/x86_64.cc
@@ -479,7 +479,8 @@ class Target_x86_64 : public Sized_target<size, false>
 		   unsigned char* view,
 		   typename elfcpp::Elf_types<size>::Elf_Addr view_address,
 		   section_size_type view_size,
-		   const Reloc_symbol_changes*);
+		   const Reloc_symbol_changes*,
+		   Relocatable_relocs*);
 
   // Scan the relocs during a relocatable link.
   void
@@ -783,12 +784,13 @@ class Target_x86_64 : public Sized_target<size, false>
     // 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>&,
+	     Output_section*, size_t, const unsigned char*,
+	     const elfcpp::Rela<size, false>&,
 	     unsigned int r_type, const Sized_symbol<size>*,
 	     const Symbol_value<size>*,
 	     unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr,
-	     section_size_type);
+	     section_size_type,
+	     Relocatable_relocs*);
 
    private:
     // Do a TLS relocation.
@@ -3351,13 +3353,15 @@ Target_x86_64<size>::Relocate::relocate(
     Target_x86_64<size>* target,
     Output_section*,
     size_t relnum,
+    const unsigned char*,
     const elfcpp::Rela<size, false>& rela,
     unsigned int r_type,
     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)
+    section_size_type view_size,
+    Relocatable_relocs*)
 {
   if (this->skip_call_tls_get_addr_)
     {
@@ -4265,7 +4269,8 @@ Target_x86_64<size>::relocate_section(
     unsigned char* view,
     typename elfcpp::Elf_types<size>::Elf_Addr address,
     section_size_type view_size,
-    const Reloc_symbol_changes* reloc_symbol_changes)
+    const Reloc_symbol_changes* reloc_symbol_changes,
+    Relocatable_relocs* rr)
 {
   gold_assert(sh_type == elfcpp::SHT_RELA);
 
@@ -4281,7 +4286,8 @@ Target_x86_64<size>::relocate_section(
     view,
     address,
     view_size,
-    reloc_symbol_changes);
+    reloc_symbol_changes,
+    rr);
 }
 
 // Apply an incremental relocation.  Incremental relocations always refer

-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list