* object.h (class Relocate_info): Add reloc_shdr and data_shdr
authorIan Lance Taylor <ian@airs.com>
Thu, 15 Oct 2009 00:33:18 +0000 (00:33 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 15 Oct 2009 00:33:18 +0000 (00:33 +0000)
fields.
* object.cc (Sized_relobj::relocate_sections): Set reloc_shdr and
data_shdr fields of relinfo.
* i386.cc (class Target_i386::Relocate): Remove ldo_addrs_ field.
(Target_i386::Relocate::relocate_tls): Don't call fix_up_ldo.  For
R_386_TLS_LDO_32, adjust based on section flags.
(Target_i386::Relocate::fix_up_ldo): Remove.

gold/ChangeLog
gold/i386.cc
gold/object.h
gold/reloc.cc

index 9b0623deddde7cc8af3bb9a66e0852257061d878..f5b1fd56427e58701f335e13e35167a28c3abf78 100644 (file)
@@ -1,3 +1,14 @@
+2009-10-14  Ian Lance Taylor  <iant@google.com>
+
+       * object.h (class Relocate_info): Add reloc_shdr and data_shdr
+       fields.
+       * object.cc (Sized_relobj::relocate_sections): Set reloc_shdr and
+       data_shdr fields of relinfo.
+       * i386.cc (class Target_i386::Relocate): Remove ldo_addrs_ field.
+       (Target_i386::Relocate::relocate_tls): Don't call fix_up_ldo.  For
+       R_386_TLS_LDO_32, adjust based on section flags.
+       (Target_i386::Relocate::fix_up_ldo): Remove.
+
 2009-10-13  Ian Lance Taylor  <iant@google.com>
 
        Add support for -pie.
index 5ac9ff4e75c38ada241cfdf4cf3ae6615f94d359..445a7ac4bdbae6916aeca99fef587c7f4fe1a2c1 100644 (file)
@@ -221,7 +221,7 @@ class Target_i386 : public Target_freebsd<32, false>
    public:
     Relocate()
       : skip_call_tls_get_addr_(false),
-       local_dynamic_type_(LOCAL_DYNAMIC_NONE), ldo_addrs_()
+       local_dynamic_type_(LOCAL_DYNAMIC_NONE)
     { }
 
     ~Relocate()
@@ -316,10 +316,6 @@ class Target_i386 : public Target_freebsd<32, false>
                 unsigned char* view,
                 section_size_type view_size);
 
-    // Fix up LDO_32 relocations we've already seen.
-    void
-    fix_up_ldo(const Relocate_info<32, false>*);
-
     // We need to keep track of which type of local dynamic relocation
     // we have seen, so that we can optimize R_386_TLS_LDO_32 correctly.
     enum Local_dynamic_type
@@ -335,8 +331,6 @@ class Target_i386 : public Target_freebsd<32, false>
     // The type of local dynamic relocation we have seen in the section
     // being relocated, if any.
     Local_dynamic_type local_dynamic_type_;
-    // A list of LDO_32 offsets, in case we find LDM after LDO_32.
-    std::vector<unsigned char*> ldo_addrs_;
   };
 
   // A class which returns the size required for a relocation type,
@@ -1937,8 +1931,6 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
 
     case elfcpp::R_386_TLS_GOTDESC:      // Global-dynamic (from ~oliva url)
     case elfcpp::R_386_TLS_DESC_CALL:
-      if (this->local_dynamic_type_ == LOCAL_DYNAMIC_NONE)
-       this->fix_up_ldo(relinfo);
       this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU;
       if (optimized_type == tls::TLSOPT_TO_LE)
         {
@@ -1997,8 +1989,6 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
                                   "TLS relocations"));
          break;
        }
-      else if (this->local_dynamic_type_ == LOCAL_DYNAMIC_NONE)
-       this->fix_up_ldo(relinfo);
       this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU;
       if (optimized_type == tls::TLSOPT_TO_LE)
        {
@@ -2023,21 +2013,19 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
       break;
 
     case elfcpp::R_386_TLS_LDO_32:       // Alternate local-dynamic
-      // This reloc can appear in debugging sections, in which case we
-      // won't see the TLS_LDM reloc.  The local_dynamic_type field
-      // tells us this.
       if (optimized_type == tls::TLSOPT_TO_LE)
        {
-          if (this->local_dynamic_type_ != LOCAL_DYNAMIC_NONE)
+         // This reloc can appear in debugging sections, in which
+         // case we must not convert to local-exec.  We decide what
+         // to do based on whether the section is marked as
+         // containing executable code.  That is what the GNU linker
+         // does as well.
+         elfcpp::Shdr<32, false> shdr(relinfo->data_shdr);
+         if ((shdr.get_sh_flags() & elfcpp::SHF_EXECINSTR) != 0)
            {
              gold_assert(tls_segment != NULL);
              value -= tls_segment->memsz();
            }
-         else
-           {
-             // We may see the LDM later.
-             this->ldo_addrs_.push_back(view);
-           }
        }
       Relocate_functions<32, false>::rel32(view, value);
       break;
@@ -2445,24 +2433,6 @@ Target_i386::Relocate::tls_ie_to_le(const Relocate_info<32, false>* relinfo,
   Relocate_functions<32, false>::rel32(view, value);
 }
 
-// If we see an LDM reloc after we handled any LDO_32 relocs, fix up
-// the LDO_32 relocs.
-
-void
-Target_i386::Relocate::fix_up_ldo(const Relocate_info<32, false>* relinfo)
-{
-  if (this->ldo_addrs_.empty())
-    return;
-  Output_segment* tls_segment = relinfo->layout->tls_segment();
-  gold_assert(tls_segment != NULL);
-  elfcpp::Elf_types<32>::Elf_Addr value = - tls_segment->memsz();
-  for (std::vector<unsigned char*>::const_iterator p = this->ldo_addrs_.begin();
-       p != this->ldo_addrs_.end();
-       ++p)
-    Relocate_functions<32, false>::rel32(*p, value);
-  this->ldo_addrs_.clear();
-}
-
 // Relocate section data.
 
 void
index 66f5dbbd6c4b21b89c4f8380bd25c3af4cbb5522..ff9668291f714c2367203fffaeacd8d317f7f530 100644 (file)
@@ -2007,8 +2007,12 @@ struct Relocate_info
   Sized_relobj<size, big_endian>* object;
   // Section index of relocation section.
   unsigned int reloc_shndx;
+  // Section header of relocation section.
+  const unsigned char* reloc_shdr;
   // Section index of section being relocated.
   unsigned int data_shndx;
+  // Section header of data section.
+  const unsigned char* data_shdr;
 
   // Return a string showing the location of a relocation.  This is
   // only used for error messages.
index d618ea4d0c020a0988659fd1283dcd7aeb571464..3018dc3daf5f497c6c7358ad95bc841a631a0ffe 100644 (file)
@@ -890,7 +890,9 @@ Sized_relobj<size, big_endian>::relocate_sections(
                  || this->relocs_must_follow_section_writes());
 
       relinfo.reloc_shndx = i;
+      relinfo.reloc_shdr = p;
       relinfo.data_shndx = index;
+      relinfo.data_shdr = pshdrs + index * This::shdr_size;
       unsigned char* view = (*pviews)[index].view;
       Address address = (*pviews)[index].address;
       section_size_type view_size = (*pviews)[index].view_size;