[GOLD] Another Output_reloc function

Alan Modra amodra@gmail.com
Thu Aug 30 01:55:00 GMT 2012


This is to support emitting R_POWERPC_RELATIVE dynamic relocs for
R_PPC64_TOC relocs on function descriptors.  R_PPC64_TOC resolves to
an offset in the output .got section, and the reloc normally doesn't
have a symbol.  OK?

	* output.h (Output_reloc::Output_reloc <output section>): Add
	is_relative param.  Adjust calls.
	(Output_reloc::add_output_section_relative): New functions.
	* output.cc (Output_reloc::Output_reloc <output section>): Handle
	is_relative.
	(Output_reloc::symbol_value): Handle SECTION_CODE.

Index: gold/output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.137
diff -u -p -r1.137 output.h
--- gold/output.h	24 Aug 2012 18:35:34 -0000	1.137
+++ gold/output.h	29 Aug 2012 10:46:42 -0000
@@ -1046,11 +1046,11 @@ class Output_reloc<elfcpp::SHT_REL, dyna
   // A reloc against the STT_SECTION symbol of an output section.
 
   Output_reloc(Output_section* os, unsigned int type, Output_data* od,
-	       Address address);
+	       Address address, bool is_relative);
 
   Output_reloc(Output_section* os, unsigned int type,
-               Sized_relobj<size, big_endian>* relobj,
-	       unsigned int shndx, Address address);
+	       Sized_relobj<size, big_endian>* relobj, unsigned int shndx,
+	       Address address, bool is_relative);
 
   // An absolute relocation with no symbol.
 
@@ -1296,14 +1296,15 @@ class Output_reloc<elfcpp::SHT_RELA, dyn
   // A reloc against the STT_SECTION symbol of an output section.
 
   Output_reloc(Output_section* os, unsigned int type, Output_data* od,
-	       Address address, Addend addend)
-    : rel_(os, type, od, address), addend_(addend)
+	       Address address, Addend addend, bool is_relative)
+    : rel_(os, type, od, address, is_relative), addend_(addend)
   { }
 
   Output_reloc(Output_section* os, unsigned int type,
                Sized_relobj<size, big_endian>* relobj,
-	       unsigned int shndx, Address address, Addend addend)
-    : rel_(os, type, relobj, shndx, address), addend_(addend)
+	       unsigned int shndx, Address address, Addend addend,
+	       bool is_relative)
+    : rel_(os, type, relobj, shndx, address, is_relative), addend_(addend)
   { }
 
   // An absolute relocation with no symbol.
@@ -1745,13 +1746,13 @@ class Output_data_reloc<elfcpp::SHT_REL,
   void
   add_output_section(Output_section* os, unsigned int type,
 		     Output_data* od, Address address)
-  { this->add(od, Output_reloc_type(os, type, od, address)); }
+  { this->add(od, Output_reloc_type(os, type, od, address, false)); }
 
   void
   add_output_section(Output_section* os, unsigned int type, Output_data* od,
 		     Sized_relobj<size, big_endian>* relobj,
                      unsigned int shndx, Address address)
-  { this->add(od, Output_reloc_type(os, type, relobj, shndx, address)); }
+  { this->add(od, Output_reloc_type(os, type, relobj, shndx, address, false)); }
 
   void
   add_output_section_generic(Output_section* os, unsigned int type,
@@ -1760,7 +1761,8 @@ class Output_data_reloc<elfcpp::SHT_REL,
   {
     gold_assert(addend == 0);
     this->add(od, Output_reloc_type(os, type, od,
-				    convert_types<Address, uint64_t>(address)));
+				    convert_types<Address, uint64_t>(address),
+				    false));
   }
 
   void
@@ -1773,9 +1775,24 @@ class Output_data_reloc<elfcpp::SHT_REL,
     Sized_relobj<size, big_endian>* sized_relobj =
       static_cast<Sized_relobj<size, big_endian>*>(relobj);
     this->add(od, Output_reloc_type(os, type, sized_relobj, shndx,
-				    convert_types<Address, uint64_t>(address)));
+				    convert_types<Address, uint64_t>(address),
+				    false));
   }
 
+  // As above, but the reloc TYPE is relative
+
+  void
+  add_output_section_relative(Output_section* os, unsigned int type,
+			      Output_data* od, Address address)
+  { this->add(od, Output_reloc_type(os, type, od, address, true)); }
+
+  void
+  add_output_section_relative(Output_section* os, unsigned int type,
+			      Output_data* od,
+			      Sized_relobj<size, big_endian>* relobj,
+			      unsigned int shndx, Address address)
+  { this->add(od, Output_reloc_type(os, type, relobj, shndx, address, true)); }
+
   // Add an absolute relocation.
 
   void
@@ -2021,14 +2038,14 @@ class Output_data_reloc<elfcpp::SHT_RELA
   void
   add_output_section(Output_section* os, unsigned int type, Output_data* od,
 		     Address address, Addend addend)
-  { this->add(od, Output_reloc_type(os, type, od, address, addend)); }
+  { this->add(od, Output_reloc_type(os, type, od, address, addend, false)); }
 
   void
   add_output_section(Output_section* os, unsigned int type, Output_data* od,
                      Sized_relobj<size, big_endian>* relobj,
 		     unsigned int shndx, Address address, Addend addend)
   { this->add(od, Output_reloc_type(os, type, relobj, shndx, address,
-                                    addend)); }
+                                    addend, false)); }
 
   void
   add_output_section_generic(Output_section* os, unsigned int type,
@@ -2037,7 +2054,8 @@ class Output_data_reloc<elfcpp::SHT_RELA
   {
     this->add(od, Output_reloc_type(os, type, od,
 				    convert_types<Address, uint64_t>(address),
-				    convert_types<Addend, uint64_t>(addend)));
+				    convert_types<Addend, uint64_t>(addend),
+				    false));
   }
 
   void
@@ -2050,7 +2068,26 @@ class Output_data_reloc<elfcpp::SHT_RELA
       static_cast<Sized_relobj<size, big_endian>*>(relobj);
     this->add(od, Output_reloc_type(os, type, sized_relobj, shndx,
 				    convert_types<Address, uint64_t>(address),
-				    convert_types<Addend, uint64_t>(addend)));
+				    convert_types<Addend, uint64_t>(addend),
+				    false));
+  }
+
+  // As above, but the reloc TYPE is relative
+
+  void
+  add_output_section_relative(Output_section* os, unsigned int type,
+			      Output_data* od, Address address, Addend addend)
+  { this->add(od, Output_reloc_type(os, type, od, address, addend, true)); }
+
+  void
+  add_output_section_relative(Output_section* os, unsigned int type,
+			      Output_data* od,
+			      Sized_relobj<size, big_endian>* relobj,
+			      unsigned int shndx, Address address,
+			      Addend addend)
+  {
+    this->add(od, Output_reloc_type(os, type, relobj, shndx,
+				    address, addend, true));
   }
 
   // Add an absolute relocation.
Index: gold/output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.169
diff -u -p -r1.169 output.cc
--- gold/output.cc	24 Aug 2012 18:35:34 -0000	1.169
+++ gold/output.cc	29 Aug 2012 10:46:42 -0000
@@ -811,9 +811,10 @@ Output_reloc<elfcpp::SHT_REL, dynamic, s
     Output_section* os,
     unsigned int type,
     Output_data* od,
-    Address address)
+    Address address,
+    bool is_relative)
   : address_(address), local_sym_index_(SECTION_CODE), type_(type),
-    is_relative_(false), is_symbolless_(false),
+    is_relative_(is_relative), is_symbolless_(is_relative),
     is_section_symbol_(true), use_plt_offset_(false), shndx_(INVALID_CODE)
 {
   // this->type_ is a bitfield; make sure TYPE fits.
@@ -832,9 +833,10 @@ Output_reloc<elfcpp::SHT_REL, dynamic, s
     unsigned int type,
     Sized_relobj<size, big_endian>* relobj,
     unsigned int shndx,
-    Address address)
+    Address address,
+    bool is_relative)
   : address_(address), local_sym_index_(SECTION_CODE), type_(type),
-    is_relative_(false), is_symbolless_(false),
+    is_relative_(is_relative), is_symbolless_(is_relative),
     is_section_symbol_(true), use_plt_offset_(false), shndx_(shndx)
 {
   gold_assert(shndx != INVALID_CODE);
@@ -1134,6 +1136,11 @@ Output_reloc<elfcpp::SHT_REL, dynamic, s
       else
 	return sym->value() + addend;
     }
+  if (this->local_sym_index_ == SECTION_CODE)
+    {
+      gold_assert(!this->use_plt_offset_);
+      return this->u1_.os->address() + addend;
+    }
   gold_assert(this->local_sym_index_ != SECTION_CODE
 	      && this->local_sym_index_ != TARGET_CODE
               && this->local_sym_index_ != INVALID_CODE

-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list