This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][gold] Mips: Add support for resolving multiple consecutive relocations


This patch adds support for resolving multiple consecutive relocations with
the same offset.

Example of multiple consecutive relocations on N32 ABI:
00000008  00000b07 R_MIPS_GPREL16    00000000   foo + 0
00000008  00000018 R_MIPS_SUB                   0
00000008  00000005 R_MIPS_HI16                  0

Regards,
Vladimir

ChangeLog -

	* aarch64.cc (Target_aarch64::Relocate::relocate): Add reloc_count
	parameter.
	* i386.cc (Target_i386::Relocate::relocate): Likewise.
	* powerpc.cc (Target_powerpc::Relocate::relocate): Likewise.
	* s390.cc (Target_s390::Relocate::relocate): Likewise.
	* sparc.cc (Target_sparc::Relocate::relocate): Likewise.
	* tilegx.cc (Target_tilegx::Relocate::relocate): Likewise.
	* x86_64.cc (Target_x86_64::Relocate::relocate): Likewise.
	* arm.cc (Target_arm::::Relocate::relocate): Likewise.
	(Target_arm::relocate_stub): Pass -1U for reloc_count to relocate.
	* mips.cc (Target_mips::Relocate::calculated_value_): New data
	member.
	(Target_mips::Relocate::calculate_only_): Likewise.
	(Target_mips::Relocate::relocate): Handle multiple consecutive
	relocations with the same offset.
	* target-reloc.h (relocate_section): Pass reloc_count to relocate.
	(apply_relocation): Pass -1U for reloc_count to relocate. 
diff --git a/gold/aarch64.cc b/gold/aarch64.cc
index b282ccf..3328dee 100644
--- a/gold/aarch64.cc
+++ b/gold/aarch64.cc
@@ -3180,10 +3180,10 @@ class Target_aarch64 : public Sized_target<size, big_endian>
     // any warnings about this relocation.
     inline bool
     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);
+	     Target_aarch64*, Output_section*, size_t, 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:
     inline typename AArch64_relocate_functions<size, big_endian>::Status
@@ -6881,6 +6881,7 @@ Target_aarch64<size, big_endian>::Relocate::relocate(
     Target_aarch64<size, big_endian>* target,
     Output_section* ,
     size_t relnum,
+    size_t,
     const unsigned char* preloc,
     const Sized_symbol<size>* gsym,
     const Symbol_value<size>* psymval,
diff --git a/gold/arm.cc b/gold/arm.cc
index ff472ea..4273ddc 100644
--- a/gold/arm.cc
+++ b/gold/arm.cc
@@ -2718,7 +2718,7 @@ class Target_arm : public Sized_target<32, big_endian>
     // any warnings about this relocation.
     inline bool
     relocate(const Relocate_info<32, big_endian>*, unsigned int,
-	     Target_arm*, Output_section*, size_t, const unsigned char*,
+	     Target_arm*, Output_section*, size_t, size_t, const unsigned char*,
 	     const Sized_symbol<32>*, const Symbol_value<32>*,
 	     unsigned char*, Arm_address, section_size_type);
 
@@ -9570,6 +9570,7 @@ Target_arm<big_endian>::Relocate::relocate(
     Target_arm* target,
     Output_section* output_section,
     size_t relnum,
+    size_t,
     const unsigned char* preloc,
     const Sized_symbol<32>* gsym,
     const Symbol_value<32>* psymval,
@@ -12573,7 +12574,7 @@ Target_arm<big_endian>::relocate_stub(
       reloc_write.put_r_info(elfcpp::elf_r_info<32>(0, r_type));
 
       relocate.relocate(relinfo, elfcpp::SHT_REL, this, output_section,
-			this->fake_relnum_for_stubs, reloc_buffer,
+			this->fake_relnum_for_stubs, -1U, reloc_buffer,
 			NULL, &symval, view + reloc_offset,
 			address + reloc_offset, reloc_size);
     }
diff --git a/gold/i386.cc b/gold/i386.cc
index 0b447ef..4807768 100644
--- a/gold/i386.cc
+++ b/gold/i386.cc
@@ -651,10 +651,10 @@ class Target_i386 : public Sized_target<32, false>
     // any warnings about this relocation.
     inline bool
     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);
+	     Target_i386*, Output_section*, size_t, size_t,
+	     const unsigned char*, const Sized_symbol<32>*,
+	     const Symbol_value<32>*, unsigned char*,
+	     elfcpp::Elf_types<32>::Elf_Addr, section_size_type);
 
    private:
     // Do a TLS relocation.
@@ -2777,6 +2777,7 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
 				Target_i386* target,
 				Output_section* output_section,
 				size_t relnum,
+				size_t,
 				const unsigned char* preloc,
 				const Sized_symbol<32>* gsym,
 				const Symbol_value<32>* psymval,
diff --git a/gold/mips.cc b/gold/mips.cc
index 95bf6db..02dc630 100644
--- a/gold/mips.cc
+++ b/gold/mips.cc
@@ -3818,6 +3818,7 @@ class Target_mips : public Sized_target<size, big_endian>
   {
    public:
     Relocate()
+      : calculated_value_(0), calculate_only_(false)
     { }
 
     ~Relocate()
@@ -3834,9 +3835,16 @@ class Target_mips : public Sized_target<size, big_endian>
     // any warnings about this relocation.
     inline bool
     relocate(const Relocate_info<size, big_endian>*, unsigned int,
-	     Target_mips*, Output_section*, size_t, const unsigned char*,
-	     const Sized_symbol<size>*, const Symbol_value<size>*,
-	     unsigned char*, Mips_address, section_size_type);
+	     Target_mips*, Output_section*, size_t, size_t,
+	     const unsigned char*, const Sized_symbol<size>*,
+	     const Symbol_value<size>*, unsigned char*, Mips_address,
+	     section_size_type);
+
+   private:
+    // Result of the relocation.
+    Valtype calculated_value_;
+    // Whether we have to calculate relocation instead of applying it.
+    bool calculate_only_;
   };
 
   // This POD class holds the dynamic relocations that should be emitted instead
@@ -11372,6 +11380,7 @@ Target_mips<size, big_endian>::Relocate::relocate(
                         Target_mips* target,
                         Output_section* output_section,
                         size_t relnum,
+                        size_t reloc_count,
                         const unsigned char* preloc,
                         const Sized_symbol<size>* gsym,
                         const Symbol_value<size>* psymval,
@@ -11386,6 +11395,10 @@ Target_mips<size, big_endian>::Relocate::relocate(
   unsigned int r_type3;
   unsigned char r_ssym;
   typename elfcpp::Elf_types<size>::Elf_Swxword r_addend;
+  // r_offset and r_type of the next relocation is needed for resolving multiple
+  // consecutive relocations with the same offset.
+  Mips_address next_r_offset = static_cast<Mips_address>(0) - 1;
+  unsigned int next_r_type = elfcpp::R_MIPS_NONE;
 
   if (rel_type == elfcpp::SHT_RELA)
     {
@@ -11402,6 +11415,17 @@ Target_mips<size, big_endian>::Relocate::relocate(
       r_ssym = Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>::
           get_r_ssym(&rela);
       r_addend = rela.get_r_addend();
+      // If this is not last relocation, get r_offset and r_type of the next
+      // relocation.
+      if (relnum + 1 < reloc_count)
+        {
+          const int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
+          const Relatype next_rela(preloc + reloc_size);
+          next_r_offset = next_rela.get_r_offset();
+          next_r_type =
+            Mips_classify_reloc<elfcpp::SHT_RELA, size, big_endian>::
+              get_r_type(&next_rela);
+        }
     }
   else
     {
@@ -11412,9 +11436,19 @@ Target_mips<size, big_endian>::Relocate::relocate(
       r_type = Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>::
 	  get_r_type(&rel);
       r_ssym = 0;
-      r_type2 = 0;
-      r_type3 = 0;
+      r_type2 = elfcpp::R_MIPS_NONE;
+      r_type3 = elfcpp::R_MIPS_NONE;
       r_addend = 0;
+      // If this is not last relocation, get r_offset and r_type of the next
+      // relocation.
+      if (relnum + 1 < reloc_count)
+        {
+          const int reloc_size = elfcpp::Elf_sizes<size>::rel_size;
+          const Reltype next_rel(preloc + reloc_size);
+          next_r_offset = next_rel.get_r_offset();
+          next_r_type = Mips_classify_reloc<elfcpp::SHT_REL, size, big_endian>::
+            get_r_type(&next_rel);
+        }
     }
 
   typedef Mips_relocate_functions<size, big_endian> Reloc_funcs;
@@ -11677,8 +11711,7 @@ Target_mips<size, big_endian>::Relocate::relocate(
   unsigned int got_offset = 0;
   int gp_offset = 0;
 
-  bool calculate_only = false;
-  Valtype calculated_value = 0;
+  // Whether we have to extract addend from instruction.
   bool extract_addend = rel_type == elfcpp::SHT_REL;
   unsigned int r_types[3] = { r_type, r_type2, r_type3 };
 
@@ -11701,10 +11734,23 @@ Target_mips<size, big_endian>::Relocate::relocate(
       if (r_types[i] == elfcpp::R_MIPS_NONE)
         break;
 
-      // TODO(Vladimir)
-      // Check if the next relocation is for the same instruction.
-      calculate_only = i == 2 ? false
-                              : r_types[i+1] != elfcpp::R_MIPS_NONE;
+      // If we didn't apply previous relocation, use its result as addend
+      // for current.
+      if (this->calculate_only_)
+        {
+          r_addend = this->calculated_value_;
+          extract_addend = false;
+        }
+
+      // In the N32 and 64-bit ABIs there may be multiple consecutive
+      // relocations for the same offset.  In that case we are
+      // supposed to treat the output of each relocation as the addend
+      // for the next.  For N64 ABI, we are checking offsets only in a
+      // third operation in a record (r_type3).
+      this->calculate_only_ =
+        (object->is_n64() && i < 2
+         ? r_types[i+1] != elfcpp::R_MIPS_NONE
+         : (r_offset == next_r_offset) && (next_r_type != elfcpp::R_MIPS_NONE));
 
       if (object->is_n64())
         {
@@ -11744,16 +11790,18 @@ Target_mips<size, big_endian>::Relocate::relocate(
           break;
         case elfcpp::R_MIPS_16:
           reloc_status = Reloc_funcs::rel16(view, object, psymval, r_addend,
-                                            extract_addend, calculate_only,
-                                            &calculated_value);
+                                            extract_addend,
+                                            this->calculate_only_,
+                                            &this->calculated_value_);
           break;
 
         case elfcpp::R_MIPS_32:
           if (should_apply_static_reloc(mips_sym, r_types[i], output_section,
                                         target))
             reloc_status = Reloc_funcs::rel32(view, object, psymval, r_addend,
-                                              extract_addend, calculate_only,
-                                              &calculated_value);
+                                              extract_addend,
+                                              this->calculate_only_,
+                                              &this->calculated_value_);
           if (mips_sym != NULL
               && (mips_sym->is_mips16() || mips_sym->is_micromips())
               && mips_sym->global_got_area() == GGA_RELOC_ONLY)
@@ -11778,14 +11826,16 @@ Target_mips<size, big_endian>::Relocate::relocate(
           if (should_apply_static_reloc(mips_sym, r_types[i], output_section,
                                         target))
             reloc_status = Reloc_funcs::rel64(view, object, psymval, r_addend,
-                                              extract_addend, calculate_only,
-                                              &calculated_value, false);
+                                              extract_addend,
+                                              this->calculate_only_,
+                                              &this->calculated_value_, false);
           else if (target->is_output_n64() && r_addend != 0)
             // Only apply the addend.  The static relocation was RELA, but the
             // dynamic relocation is REL, so we need to apply the addend.
             reloc_status = Reloc_funcs::rel64(view, object, psymval, r_addend,
-                                              extract_addend, calculate_only,
-                                              &calculated_value, true);
+                                              extract_addend,
+                                              this->calculate_only_,
+                                              &this->calculated_value_, true);
           break;
         case elfcpp::R_MIPS_REL32:
           gold_unreachable();
@@ -11793,8 +11843,8 @@ Target_mips<size, big_endian>::Relocate::relocate(
         case elfcpp::R_MIPS_PC32:
           reloc_status = Reloc_funcs::relpc32(view, object, psymval, address,
                                               r_addend, extract_addend,
-                                              calculate_only,
-                                              &calculated_value);
+                                              this->calculate_only_,
+                                              &this->calculated_value_);
           break;
 
         case elfcpp::R_MIPS16_26:
@@ -11806,8 +11856,8 @@ Target_mips<size, big_endian>::Relocate::relocate(
         case elfcpp::R_MICROMIPS_26_S1:
           reloc_status = Reloc_funcs::rel26(view, object, psymval, address,
               gsym == NULL, r_addend, extract_addend, gsym, cross_mode_jump,
-              r_types[i], target->jal_to_bal(), calculate_only,
-              &calculated_value);
+              r_types[i], target->jal_to_bal(), this->calculate_only_,
+              &this->calculated_value_);
           break;
 
         case elfcpp::R_MIPS_HI16:
@@ -11818,8 +11868,9 @@ Target_mips<size, big_endian>::Relocate::relocate(
                                                    r_addend, address,
                                                    gp_disp, r_types[i],
                                                    extract_addend, 0,
-                                                   target, calculate_only,
-                                                   &calculated_value);
+                                                   target,
+                                                   this->calculate_only_,
+                                                   &this->calculated_value_);
           else if (rel_type == elfcpp::SHT_REL)
             reloc_status = Reloc_funcs::relhi16(view, object, psymval, r_addend,
                                                 address, gp_disp, r_types[i],
@@ -11835,8 +11886,8 @@ Target_mips<size, big_endian>::Relocate::relocate(
           reloc_status = Reloc_funcs::rello16(target, view, object, psymval,
                                               r_addend, extract_addend, address,
                                               gp_disp, r_types[i], r_sym,
-                                              rel_type, calculate_only,
-                                              &calculated_value);
+                                              rel_type, this->calculate_only_,
+                                              &this->calculated_value_);
           break;
 
         case elfcpp::R_MIPS_LITERAL:
@@ -11856,42 +11907,43 @@ Target_mips<size, big_endian>::Relocate::relocate(
                                              target->adjusted_gp_value(object),
                                              r_addend, extract_addend,
                                              gsym == NULL, r_types[i],
-                                             calculate_only, &calculated_value);
+                                             this->calculate_only_,
+                                             &this->calculated_value_);
           break;
 
         case elfcpp::R_MIPS_PC16:
           reloc_status = Reloc_funcs::relpc16(view, object, psymval, address,
                                               r_addend, extract_addend,
-                                              calculate_only,
-                                              &calculated_value);
+                                              this->calculate_only_,
+                                              &this->calculated_value_);
           break;
 
         case elfcpp::R_MIPS_PC21_S2:
           reloc_status = Reloc_funcs::relpc21(view, object, psymval, address,
                                               r_addend, extract_addend,
-                                              calculate_only,
-                                              &calculated_value);
+                                              this->calculate_only_,
+                                              &this->calculated_value_);
           break;
 
         case elfcpp::R_MIPS_PC26_S2:
           reloc_status = Reloc_funcs::relpc26(view, object, psymval, address,
                                               r_addend, extract_addend,
-                                              calculate_only,
-                                              &calculated_value);
+                                              this->calculate_only_,
+                                              &this->calculated_value_);
           break;
 
         case elfcpp::R_MIPS_PC18_S3:
           reloc_status = Reloc_funcs::relpc18(view, object, psymval, address,
                                               r_addend, extract_addend,
-                                              calculate_only,
-                                              &calculated_value);
+                                              this->calculate_only_,
+                                              &this->calculated_value_);
           break;
 
         case elfcpp::R_MIPS_PC19_S2:
           reloc_status = Reloc_funcs::relpc19(view, object, psymval, address,
                                               r_addend, extract_addend,
-                                              calculate_only,
-                                              &calculated_value);
+                                              this->calculate_only_,
+                                              &this->calculated_value_);
           break;
 
         case elfcpp::R_MIPS_PCHI16:
@@ -11899,8 +11951,8 @@ Target_mips<size, big_endian>::Relocate::relocate(
             reloc_status = Reloc_funcs::do_relpchi16(view, object, psymval,
                                                      r_addend, address,
                                                      extract_addend, 0,
-                                                     calculate_only,
-                                                     &calculated_value);
+                                                     this->calculate_only_,
+                                                     &this->calculated_value_);
           else if (rel_type == elfcpp::SHT_REL)
             reloc_status = Reloc_funcs::relpchi16(view, object, psymval,
                                                   r_addend, address, r_sym,
@@ -11912,36 +11964,36 @@ Target_mips<size, big_endian>::Relocate::relocate(
         case elfcpp::R_MIPS_PCLO16:
           reloc_status = Reloc_funcs::relpclo16(view, object, psymval, r_addend,
                                                 extract_addend, address, r_sym,
-                                                rel_type, calculate_only,
-                                                &calculated_value);
+                                                rel_type, this->calculate_only_,
+                                                &this->calculated_value_);
           break;
         case elfcpp::R_MICROMIPS_PC7_S1:
           reloc_status = Reloc_funcs::relmicromips_pc7_s1(view, object, psymval,
-                                                        address, r_addend,
-                                                        extract_addend,
-                                                        calculate_only,
-                                                        &calculated_value);
+                                                      address, r_addend,
+                                                      extract_addend,
+                                                      this->calculate_only_,
+                                                      &this->calculated_value_);
           break;
         case elfcpp::R_MICROMIPS_PC10_S1:
           reloc_status = Reloc_funcs::relmicromips_pc10_s1(view, object,
-                                                       psymval, address,
-                                                       r_addend, extract_addend,
-                                                       calculate_only,
-                                                       &calculated_value);
+                                                      psymval, address,
+                                                      r_addend, extract_addend,
+                                                      this->calculate_only_,
+                                                      &this->calculated_value_);
           break;
         case elfcpp::R_MICROMIPS_PC16_S1:
           reloc_status = Reloc_funcs::relmicromips_pc16_s1(view, object,
-                                                       psymval, address,
-                                                       r_addend, extract_addend,
-                                                       calculate_only,
-                                                       &calculated_value);
+                                                      psymval, address,
+                                                      r_addend, extract_addend,
+                                                      this->calculate_only_,
+                                                      &this->calculated_value_);
           break;
         case elfcpp::R_MIPS_GPREL32:
           reloc_status = Reloc_funcs::relgprel32(view, object, psymval,
                                               target->adjusted_gp_value(object),
                                               r_addend, extract_addend,
-                                              calculate_only,
-                                              &calculated_value);
+                                              this->calculate_only_,
+                                              &this->calculated_value_);
           break;
         case elfcpp::R_MIPS_GOT_HI16:
         case elfcpp::R_MIPS_CALL_HI16:
@@ -11957,8 +12009,8 @@ Target_mips<size, big_endian>::Relocate::relocate(
                                                            object, r_addend);
           gp_offset = target->got_section()->gp_offset(got_offset, object);
           reloc_status = Reloc_funcs::relgot_hi16(view, gp_offset,
-                                                  calculate_only,
-                                                  &calculated_value);
+                                                  this->calculate_only_,
+                                                  &this->calculated_value_);
           update_got_entry = changed_symbol_value;
           break;
 
@@ -11976,8 +12028,8 @@ Target_mips<size, big_endian>::Relocate::relocate(
                                                            object, r_addend);
           gp_offset = target->got_section()->gp_offset(got_offset, object);
           reloc_status = Reloc_funcs::relgot_lo16(view, gp_offset,
-                                                  calculate_only,
-                                                  &calculated_value);
+                                                  this->calculate_only_,
+                                                  &this->calculated_value_);
           update_got_entry = changed_symbol_value;
           break;
 
@@ -11995,12 +12047,12 @@ Target_mips<size, big_endian>::Relocate::relocate(
           gp_offset = target->got_section()->gp_offset(got_offset, object);
           if (eh_reloc(r_types[i]))
             reloc_status = Reloc_funcs::releh(view, gp_offset,
-                                              calculate_only,
-                                              &calculated_value);
+                                              this->calculate_only_,
+                                              &this->calculated_value_);
           else
             reloc_status = Reloc_funcs::relgot(view, gp_offset,
-                                               calculate_only,
-                                               &calculated_value);
+                                               this->calculate_only_,
+                                               &this->calculated_value_);
           break;
         case elfcpp::R_MIPS_CALL16:
         case elfcpp::R_MIPS16_CALL16:
@@ -12011,7 +12063,8 @@ Target_mips<size, big_endian>::Relocate::relocate(
                                                          object);
           gp_offset = target->got_section()->gp_offset(got_offset, object);
           reloc_status = Reloc_funcs::relgot(view, gp_offset,
-                                             calculate_only, &calculated_value);
+                                             this->calculate_only_,
+                                             &this->calculated_value_);
           // TODO(sasa): We should also initialize update_got_entry
           // in other place swhere relgot is called.
           update_got_entry = changed_symbol_value;
@@ -12027,18 +12080,18 @@ Target_mips<size, big_endian>::Relocate::relocate(
                                                              object);
               gp_offset = target->got_section()->gp_offset(got_offset, object);
               reloc_status = Reloc_funcs::relgot(view, gp_offset,
-                                                 calculate_only,
-                                                 &calculated_value);
+                                                 this->calculate_only_,
+                                                 &this->calculated_value_);
             }
           else
             {
               if (rel_type == elfcpp::SHT_RELA)
                 reloc_status = Reloc_funcs::do_relgot16_local(view, object,
-                                                         psymval, r_addend,
-                                                         extract_addend, 0,
-                                                         target,
-                                                         calculate_only,
-                                                         &calculated_value);
+                                                      psymval, r_addend,
+                                                      extract_addend, 0,
+                                                      target,
+                                                      this->calculate_only_,
+                                                      &this->calculated_value_);
               else if (rel_type == elfcpp::SHT_REL)
                 reloc_status = Reloc_funcs::relgot16_local(view, object,
                                                            psymval, r_addend,
@@ -12062,8 +12115,9 @@ Target_mips<size, big_endian>::Relocate::relocate(
                                                            GOT_TYPE_TLS_PAIR,
                                                            object, r_addend);
           gp_offset = target->got_section()->gp_offset(got_offset, object);
-          reloc_status = Reloc_funcs::relgot(view, gp_offset, calculate_only,
-                                             &calculated_value);
+          reloc_status = Reloc_funcs::relgot(view, gp_offset,
+                                             this->calculate_only_,
+                                             &this->calculated_value_);
           break;
 
         case elfcpp::R_MIPS_TLS_GOTTPREL:
@@ -12078,8 +12132,9 @@ Target_mips<size, big_endian>::Relocate::relocate(
                                                            GOT_TYPE_TLS_OFFSET,
                                                            object, r_addend);
           gp_offset = target->got_section()->gp_offset(got_offset, object);
-          reloc_status = Reloc_funcs::relgot(view, gp_offset, calculate_only,
-                                             &calculated_value);
+          reloc_status = Reloc_funcs::relgot(view, gp_offset,
+                                             this->calculate_only_,
+                                             &this->calculated_value_);
           break;
 
         case elfcpp::R_MIPS_TLS_LDM:
@@ -12089,24 +12144,25 @@ Target_mips<size, big_endian>::Relocate::relocate(
           // the module index.
           got_offset = target->got_section()->tls_ldm_offset(object);
           gp_offset = target->got_section()->gp_offset(got_offset, object);
-          reloc_status = Reloc_funcs::relgot(view, gp_offset, calculate_only,
-                                             &calculated_value);
+          reloc_status = Reloc_funcs::relgot(view, gp_offset,
+                                             this->calculate_only_,
+                                             &this->calculated_value_);
           break;
 
         case elfcpp::R_MIPS_GOT_PAGE:
         case elfcpp::R_MICROMIPS_GOT_PAGE:
           reloc_status = Reloc_funcs::relgotpage(target, view, object, psymval,
                                                  r_addend, extract_addend,
-                                                 calculate_only,
-                                                 &calculated_value);
+                                                 this->calculate_only_,
+                                                 &this->calculated_value_);
           break;
 
         case elfcpp::R_MIPS_GOT_OFST:
         case elfcpp::R_MICROMIPS_GOT_OFST:
           reloc_status = Reloc_funcs::relgotofst(target, view, object, psymval,
                                                  r_addend, extract_addend,
-                                                 local, calculate_only,
-                                                 &calculated_value);
+                                                 local, this->calculate_only_,
+                                                 &this->calculated_value_);
           break;
 
         case elfcpp::R_MIPS_JALR:
@@ -12121,8 +12177,8 @@ Target_mips<size, big_endian>::Relocate::relocate(
                                                 cross_mode_jump, r_types[i],
                                                 target->jalr_to_bal(),
                                                 target->jr_to_b(),
-                                                calculate_only,
-                                                &calculated_value);
+                                                this->calculate_only_,
+                                                &this->calculated_value_);
           break;
 
         case elfcpp::R_MIPS_TLS_DTPREL_HI16:
@@ -12130,65 +12186,73 @@ Target_mips<size, big_endian>::Relocate::relocate(
         case elfcpp::R_MICROMIPS_TLS_DTPREL_HI16:
           reloc_status = Reloc_funcs::tlsrelhi16(view, object, psymval,
                                                  elfcpp::DTP_OFFSET, r_addend,
-                                                 extract_addend, calculate_only,
-                                                 &calculated_value);
+                                                 extract_addend,
+                                                 this->calculate_only_,
+                                                 &this->calculated_value_);
           break;
         case elfcpp::R_MIPS_TLS_DTPREL_LO16:
         case elfcpp::R_MIPS16_TLS_DTPREL_LO16:
         case elfcpp::R_MICROMIPS_TLS_DTPREL_LO16:
           reloc_status = Reloc_funcs::tlsrello16(view, object, psymval,
                                                  elfcpp::DTP_OFFSET, r_addend,
-                                                 extract_addend, calculate_only,
-                                                 &calculated_value);
+                                                 extract_addend,
+                                                 this->calculate_only_,
+                                                 &this->calculated_value_);
           break;
         case elfcpp::R_MIPS_TLS_DTPREL32:
         case elfcpp::R_MIPS_TLS_DTPREL64:
           reloc_status = Reloc_funcs::tlsrel32(view, object, psymval,
                                                elfcpp::DTP_OFFSET, r_addend,
-                                               extract_addend, calculate_only,
-                                               &calculated_value);
+                                               extract_addend,
+                                               this->calculate_only_,
+                                               &this->calculated_value_);
           break;
         case elfcpp::R_MIPS_TLS_TPREL_HI16:
         case elfcpp::R_MIPS16_TLS_TPREL_HI16:
         case elfcpp::R_MICROMIPS_TLS_TPREL_HI16:
           reloc_status = Reloc_funcs::tlsrelhi16(view, object, psymval,
                                                  elfcpp::TP_OFFSET, r_addend,
-                                                 extract_addend, calculate_only,
-                                                 &calculated_value);
+                                                 extract_addend,
+                                                 this->calculate_only_,
+                                                 &this->calculated_value_);
           break;
         case elfcpp::R_MIPS_TLS_TPREL_LO16:
         case elfcpp::R_MIPS16_TLS_TPREL_LO16:
         case elfcpp::R_MICROMIPS_TLS_TPREL_LO16:
           reloc_status = Reloc_funcs::tlsrello16(view, object, psymval,
                                                  elfcpp::TP_OFFSET, r_addend,
-                                                 extract_addend, calculate_only,
-                                                 &calculated_value);
+                                                 extract_addend,
+                                                 this->calculate_only_,
+                                                 &this->calculated_value_);
           break;
         case elfcpp::R_MIPS_TLS_TPREL32:
         case elfcpp::R_MIPS_TLS_TPREL64:
           reloc_status = Reloc_funcs::tlsrel32(view, object, psymval,
                                                elfcpp::TP_OFFSET, r_addend,
-                                               extract_addend, calculate_only,
-                                               &calculated_value);
+                                               extract_addend,
+                                               this->calculate_only_,
+                                               &this->calculated_value_);
           break;
         case elfcpp::R_MIPS_SUB:
         case elfcpp::R_MICROMIPS_SUB:
           reloc_status = Reloc_funcs::relsub(view, object, psymval, r_addend,
                                              extract_addend,
-                                             calculate_only, &calculated_value);
+                                             this->calculate_only_,
+                                             &this->calculated_value_);
           break;
         case elfcpp::R_MIPS_HIGHER:
         case elfcpp::R_MICROMIPS_HIGHER:
           reloc_status = Reloc_funcs::relhigher(view, object, psymval, r_addend,
-                                                extract_addend, calculate_only,
-                                                &calculated_value);
+                                                extract_addend,
+                                                this->calculate_only_,
+                                                &this->calculated_value_);
           break;
         case elfcpp::R_MIPS_HIGHEST:
         case elfcpp::R_MICROMIPS_HIGHEST:
           reloc_status = Reloc_funcs::relhighest(view, object, psymval,
                                                  r_addend, extract_addend,
-                                                 calculate_only,
-                                                 &calculated_value);
+                                                 this->calculate_only_,
+                                                 &this->calculated_value_);
           break;
         default:
           gold_error_at_location(relinfo, relnum, r_offset,
@@ -12205,8 +12269,6 @@ Target_mips<size, big_endian>::Relocate::relocate(
           else
             got->update_got_entry(got_offset, psymval->value(object, 0));
         }
-
-      r_addend = calculated_value;
     }
 
   bool jal_shuffle = jal_reloc(r_type) ? !parameters->options().relocatable()
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index 1477a10..2172974 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -1170,10 +1170,10 @@ class Target_powerpc : public Sized_target<size, big_endian>
     // any warnings about this relocation.
     inline bool
     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);
+	     Target_powerpc*, Output_section*, size_t, 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);
   };
 
   class Relocate_comdat_behavior
@@ -7582,6 +7582,7 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
     Target_powerpc* target,
     Output_section* os,
     size_t relnum,
+    size_t,
     const unsigned char* preloc,
     const Sized_symbol<size>* gsym,
     const Symbol_value<size>* psymval,
diff --git a/gold/s390.cc b/gold/s390.cc
index a188268..16875a9 100644
--- a/gold/s390.cc
+++ b/gold/s390.cc
@@ -582,10 +582,10 @@ class Target_s390 : public Sized_target<size, true>
     // any warnings about this relocation.
     inline bool
     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);
+	     Target_s390*, Output_section*, size_t, 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:
     // Do a TLS relocation.
@@ -3191,6 +3191,7 @@ Target_s390<size>::Relocate::relocate(
     Target_s390<size>* target,
     Output_section*,
     size_t relnum,
+    size_t,
     const unsigned char* preloc,
     const Sized_symbol<size>* gsym,
     const Symbol_value<size>* psymval,
diff --git a/gold/sparc.cc b/gold/sparc.cc
index a9cb93a..031e24d 100644
--- a/gold/sparc.cc
+++ b/gold/sparc.cc
@@ -329,10 +329,10 @@ class Target_sparc : public Sized_target<size, big_endian>
     // any warnings about this relocation.
     inline bool
     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);
+	     Target_sparc*, Output_section*, size_t, bool,
+	     const unsigned char*, const Sized_symbol<size>*,
+	     const Symbol_value<size>*, unsigned char*,
+	     typename elfcpp::Elf_types<size>::Elf_Addr, section_size_type);
 
    private:
     // Do a TLS relocation.
@@ -3275,6 +3275,7 @@ Target_sparc<size, big_endian>::Relocate::relocate(
 			Target_sparc* target,
 			Output_section*,
 			size_t relnum,
+			bool,
 			const unsigned char* preloc,
 			const Sized_symbol<size>* gsym,
 			const Symbol_value<size>* psymval,
diff --git a/gold/target-reloc.h b/gold/target-reloc.h
index c8b86c6..9e5f397 100644
--- a/gold/target-reloc.h
+++ b/gold/target-reloc.h
@@ -401,8 +401,8 @@ relocate_section(
 	v = NULL;
 
       if (!relocate.relocate(relinfo, Classify_reloc::sh_type, target,
-			     output_section, i, prelocs, sym, psymval,
-			     v, view_address + offset, view_size))
+			     output_section, i, reloc_count, prelocs, sym,
+			     psymval, v, view_address + offset, view_size))
 	continue;
 
       if (v == NULL)
@@ -461,7 +461,7 @@ apply_relocation(const Relocate_info<size, big_endian>* relinfo,
 
   Relocate relocate;
   relocate.relocate(relinfo, elfcpp::SHT_RELA, target, NULL,
-		    -1U, relbuf, sym, &symval,
+		    -1U, -1U, relbuf, sym, &symval,
 		    view + r_offset, address + r_offset, view_size);
 }
 
diff --git a/gold/tilegx.cc b/gold/tilegx.cc
index 07c03fc..3bf3a42 100644
--- a/gold/tilegx.cc
+++ b/gold/tilegx.cc
@@ -532,10 +532,10 @@ class Target_tilegx : public Sized_target<size, big_endian>
     // any warnings about this relocation.
     inline bool
     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);
+	     Target_tilegx*, Output_section*, size_t, 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);
   };
 
   // Adjust TLS relocation type based on the options and whether this
@@ -4336,6 +4336,7 @@ Target_tilegx<size, big_endian>::Relocate::relocate(
     Target_tilegx<size, big_endian>* target,
     Output_section*,
     size_t relnum,
+    size_t,
     const unsigned char* preloc,
     const Sized_symbol<size>* gsym,
     const Symbol_value<size>* psymval,
diff --git a/gold/x86_64.cc b/gold/x86_64.cc
index 7f1742d..a54efd7 100644
--- a/gold/x86_64.cc
+++ b/gold/x86_64.cc
@@ -961,10 +961,10 @@ class Target_x86_64 : public Sized_target<size, false>
     // any warnings about this relocation.
     inline bool
     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);
+	     Target_x86_64*, Output_section*, size_t, 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:
     // Do a TLS relocation.
@@ -4027,6 +4027,7 @@ Target_x86_64<size>::Relocate::relocate(
     Target_x86_64<size>* target,
     Output_section*,
     size_t relnum,
+    size_t,
     const unsigned char* preloc,
     const Sized_symbol<size>* gsym,
     const Symbol_value<size>* psymval,

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]