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]

Re: [ld-new] gold patch committed: Handle LDO_32 following LDM


Cary Coutant <ccoutant@google.com> writes:

>>> But output_section->flags() is readily available in
>>> Relocate::relocate() -- wouldn't that do? ÂWhy not just pass
>>> output_section -- or (output_section->flags() & elfcpp::SHF_EXECINSTR)
>>> -- to relocate_tls()?
>>
>> What matters is not the flags of the output section, but the flags of
>> the input section. ÂThat is, I'm concerned about crazy people using
>> linker scripts. ÂIt wouldn't actually be that hard to pass the flags
>> down from Sized_relobj::relocate_sections, perhaps stuffing them in
>> Relocate_info. ÂDo you think it's worth it?
>
> Yes, I think adding the flags to Relocate_info would be much cleaner.
> (I don't have much sympathy, though, for anyone who puts an executable
> input section into a non-executable output section, but I guess we
> should support that.)

I committed this plan as follows.

Ian


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.


Index: i386.cc
===================================================================
RCS file: /cvs/src/src/gold/i386.cc,v
retrieving revision 1.94
diff -p -u -r1.94 i386.cc
--- i386.cc	14 Oct 2009 05:25:01 -0000	1.94
+++ i386.cc	15 Oct 2009 00:30:35 -0000
@@ -221,7 +221,7 @@ class Target_i386 : public Target_freebs
    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_freebs
 		 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_freebs
     // 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(cons
 
     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(cons
 				   "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(cons
       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(cons
   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: object.h
===================================================================
RCS file: /cvs/src/src/gold/object.h,v
retrieving revision 1.81
diff -p -u -r1.81 object.h
--- object.h	9 Oct 2009 23:18:19 -0000	1.81
+++ object.h	15 Oct 2009 00:30:37 -0000
@@ -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: reloc.cc
===================================================================
RCS file: /cvs/src/src/gold/reloc.cc,v
retrieving revision 1.47
diff -p -u -r1.47 reloc.cc
--- reloc.cc	13 Oct 2009 21:17:43 -0000	1.47
+++ reloc.cc	15 Oct 2009 00:30:37 -0000
@@ -890,7 +890,9 @@ Sized_relobj<size, big_endian>::relocate
 		  || 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;

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