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]

[committed] TILE-Gx GOLD: better offset ranges for large got.


This patch adjust the value of _GLOBAL_OFFSET_TABLE_ for got bigger
than 0x8000 bytes, so that the 16 bit relocations have a greater
chance of working.

Walter

	* tilegx.cc (Target_tilegx::do_finalize_sections): Adjust
	global_offset_table_ value for larget got.
	(Target_tilegx::Relocate::relocate): Handle adjusted got value.

Index: gold/tilegx.cc
===================================================================
RCS file: /cvs/src/src/gold/tilegx.cc,v
retrieving revision 1.1
diff -u -p -r1.1 tilegx.cc
--- gold/tilegx.cc	15 Sep 2012 17:11:28 -0000	1.1
+++ gold/tilegx.cc	3 Oct 2012 00:45:23 -0000
@@ -4256,6 +4256,13 @@ Target_tilegx<size, big_endian>::do_fina
     {
       uint64_t data_size = this->got_->current_data_size();
       symtab->get_sized_symbol<size>(sym)->set_symsize(data_size);
+
+      // If the .got section is more than 0x8000 bytes, we add
+      // 0x8000 to the value of _GLOBAL_OFFSET_TABLE_, so that 16
+      // bit relocations have a greater chance of working.
+      if (data_size >= 0x8000)
+        symtab->get_sized_symbol<size>(sym)->set_value(
+          symtab->get_sized_symbol<size>(sym)->value() + 0x8000);
     }
 
   if (parameters->doing_static_link()
@@ -4347,7 +4354,10 @@ Target_tilegx<size, big_endian>::Relocat
   // Get the GOT offset if needed.
   // For tilegx, the GOT pointer points to the start of the GOT section.
   bool have_got_offset = false;
-  unsigned int got_offset = 0;
+  int got_offset = 0;
+  int got_base = target->got_ != NULL
+                 ? target->got_->current_data_size() >= 0x8000 ? 0x8000 : 0
+                 : 0;
   unsigned int got_type = GOT_TYPE_STANDARD;
   bool always_apply_relocation = false;
   switch (r_type)
@@ -4361,13 +4371,14 @@ Target_tilegx<size, big_endian>::Relocat
       if (gsym != NULL)
         {
           gold_assert(gsym->has_got_offset(got_type));
-          got_offset = gsym->got_offset(got_type);
+          got_offset = gsym->got_offset(got_type) - got_base;
         }
       else
         {
           unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
           gold_assert(object->local_has_got_offset(r_sym, got_type));
-          got_offset = object->local_got_offset(r_sym, got_type);
+          got_offset =
+            object->local_got_offset(r_sym, got_type) - got_base;
         }
       have_got_offset = true;
       break;
@@ -4590,12 +4601,13 @@ Target_tilegx<size, big_endian>::Relocat
               if (have_got_offset) {
                 if (gsym != NULL) {
                   gold_assert(gsym->has_got_offset(got_type));
-                  got_offset = gsym->got_offset(got_type);
+                  got_offset = gsym->got_offset(got_type) - got_base;
                 } else {
                   unsigned int r_sym
                      = elfcpp::elf_r_sym<size>(rela.get_r_info());
                   gold_assert(object->local_has_got_offset(r_sym, got_type));
-                  got_offset = object->local_got_offset(r_sym, got_type);
+                  got_offset =
+                    object->local_got_offset(r_sym, got_type) - got_base;
                 }
               }
 


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