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]

gold patch committed: More adjustments to .interp


The GNU linker create a PT_INTERP segment whenever it sees a .interp
section, even if --dynamic-linker is specified.  I think this is
moderately broken; when possible, we should rely on command line options
rather than magic section names.  However, glibc expects this behaviour,
so this patch changes gold to be compatible with GNU ld.  Committed to
mainline.

Ian


2011-06-19  Ian Lance Taylor  <iant@google.com>

	PR gold/12880
	* layout.cc (Layout::attach_allocated_section_to_segment): Add a
	.interp section to a PT_INTERP segment even if we have seen a
	--dynamic-linker option.  Don't do it if we have seen a PHDRS
	clause in a linker script.
	(Layout::finalize): Don't create a .interp section if we've
	already create a PT_INTERP segment.
	(Layout::create_interp): Always call choose_output_section (revert
	patch of 2011-06-17).  Don't create PT_INTERP segment.
	* script-sections.cc
	(Script_sections::create_note_and_tls_segments): Add a .interp
	section to a PT_INTERP segment even if we have seen a
	--dynamic-linker option.


Index: layout.cc
===================================================================
RCS file: /cvs/src/src/gold/layout.cc,v
retrieving revision 1.203
diff -p -u -r1.203 layout.cc
--- layout.cc	18 Jun 2011 22:53:23 -0000	1.203
+++ layout.cc	19 Jun 2011 22:04:22 -0000
@@ -1547,18 +1547,17 @@ Layout::attach_allocated_section_to_segm
       this->relro_segment_->add_output_section_to_nonload(os, seg_flags);
     }
 
-  // If we are making a shared library, and we see a section named
-  // .interp, and the -dynamic-linker option was not used, then put
-  // the .interp section into a PT_INTERP segment.  This is for GNU ld
-  // compatibility.  If making an executable, or if the
-  // -dynamic-linker option was used, we will create the section and
-  // segment in Layout::create_interp.
+  // If we see a section named .interp, put it into a PT_INTERP
+  // segment.  This seems broken to me, but this is what GNU ld does,
+  // and glibc expects it.
   if (strcmp(os->name(), ".interp") == 0
-      && parameters->options().shared()
-      && parameters->options().dynamic_linker() == NULL)
+      && !this->script_options_->saw_phdrs_clause())
     {
       if (this->interp_segment_ == NULL)
 	this->make_output_segment(elfcpp::PT_INTERP, seg_flags);
+      else
+	gold_warning(_("multiple '.interp' sections in input files "
+		       "may cause confusing PT_INTERP segment"));
       this->interp_segment_->add_output_section_to_nonload(os, seg_flags);
     }
 }
@@ -2183,9 +2182,11 @@ Layout::finalize(const Input_objects* in
 				  &versions);
 
       // Create the .interp section to hold the name of the
-      // interpreter, and put it in a PT_INTERP segment.
-      if (!parameters->options().shared()
-	  || parameters->options().dynamic_linker() != NULL)
+      // interpreter, and put it in a PT_INTERP segment.  Don't do it
+      // if we saw a .interp section in an input file.
+      if ((!parameters->options().shared()
+	   || parameters->options().dynamic_linker() != NULL)
+	  && this->interp_segment_ == NULL)
         this->create_interp(target);
 
       // Finish the .dynamic section to hold the dynamic data, and put
@@ -3879,31 +3880,12 @@ Layout::create_interp(const Target* targ
 
   Output_section_data* odata = new Output_data_const(interp, len, 1);
 
-  Output_section* osec;
-
-  // If we are using a SECTIONS clause, let it decide where the
-  // .interp section should go.  Otherwise always create a new section
-  // so that this .interp section does not get confused with any
-  // section of the same name in the program.
-  if (this->script_options_->saw_sections_clause())
-    osec = this->choose_output_section(NULL, ".interp", elfcpp::SHT_PROGBITS,
-				       elfcpp::SHF_ALLOC, false, ORDER_INTERP,
-				       false);
-  else
-    {
-      const char* n = this->namepool_.add("interp", false, NULL);
-      osec = this->make_output_section(n, elfcpp::SHT_PROGBITS,
-				       elfcpp::SHF_ALLOC, ORDER_INTERP, false);
-    }
-
+  Output_section* osec = this->choose_output_section(NULL, ".interp",
+						     elfcpp::SHT_PROGBITS,
+						     elfcpp::SHF_ALLOC,
+						     false, ORDER_INTERP,
+						     false);
   osec->add_output_section_data(odata);
-
-  if (!this->script_options_->saw_phdrs_clause())
-    {
-      Output_segment* oseg = this->make_output_segment(elfcpp::PT_INTERP,
-						       elfcpp::PF_R);
-      oseg->add_output_section_to_nonload(osec, elfcpp::PF_R);
-    }
 }
 
 // Add dynamic tags for the PLT and the dynamic relocs.  This is
Index: script-sections.cc
===================================================================
RCS file: /cvs/src/src/gold/script-sections.cc,v
retrieving revision 1.51
diff -p -u -r1.51 script-sections.cc
--- script-sections.cc	17 Jun 2011 13:00:01 -0000	1.51
+++ script-sections.cc	19 Jun 2011 22:04:22 -0000
@@ -3938,12 +3938,9 @@ Script_sections::create_note_and_tls_seg
 	}
 
       // If we are making a shared library, and we see a section named
-      // .interp, and the -dynamic-linker option was not used, then
-      // put the .interp section in a PT_INTERP segment.  This is for
-      // GNU ld compatibility.
-      if (strcmp((*p)->name(), ".interp") == 0
-	  && parameters->options().shared()
-	  && parameters->options().dynamic_linker() == NULL)
+      // .interp then put the .interp section in a PT_INTERP segment.
+      // This is for GNU ld compatibility.
+      if (strcmp((*p)->name(), ".interp") == 0)
 	{
 	  elfcpp::Elf_Word seg_flags =
 	    Layout::section_flags_to_segment((*p)->flags());

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