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: Don't check discarded deferred .eh_frame section


The code that handles deferred .eh_frame sections when using a plugin
had a bug: it checked whether the section was included in the link
before doing the .eh_frame handling.  Unfortunately, the check for an
included section always indicates that a .eh_frame section is not
included, because .eh_frame sections are handled specially.  This led to
http://gcc.gnu.org/PR56840 , in which .eh_frame sections in archives are
discarded inappropriately.

This patch fixes the problem.  Committed to mainline.

Ian


2013-04-04  Ian Lance Taylor  <iant@google.com>

	GCC PR c++/56840
	* object.cc (do_layout_deferred_sections): Handle .eh_frame
	sections before checking whether they are included in the link.


Index: object.cc
===================================================================
RCS file: /cvs/src/src/gold/object.cc,v
retrieving revision 1.162
diff -u -p -r1.162 object.cc
--- object.cc	10 Mar 2013 23:08:18 -0000	1.162
+++ object.cc	4 Apr 2013 16:43:41 -0000
@@ -1815,19 +1815,21 @@ Sized_relobj_file<size, big_endian>::do_
        ++deferred)
     {
       typename This::Shdr shdr(deferred->shdr_data_);
-      // If the section is not included, it is because the garbage collector
-      // decided it is not needed.  Avoid reverting that decision.
-      if (!this->is_section_included(deferred->shndx_))
-	continue;
 
-      if (parameters->options().relocatable()
-	  || deferred->name_ != ".eh_frame"
-	  || !this->check_eh_frame_flags(&shdr))
-	this->layout_section(layout, deferred->shndx_, deferred->name_.c_str(),
-			     shdr, deferred->reloc_shndx_,
-			     deferred->reloc_type_);
-      else
-	{
+      if (!parameters->options().relocatable()
+	  && deferred->name_ == ".eh_frame"
+	  && this->check_eh_frame_flags(&shdr))
+	{
+	  // Checking is_section_included is not reliable for
+	  // .eh_frame sections, because they do not have an output
+	  // section.  This is not a problem normally because we call
+	  // layout_eh_frame_section unconditionally, but when
+	  // deferring sections that is not true.  We don't want to
+	  // keep all .eh_frame sections because that will cause us to
+	  // keep all sections that they refer to, which is the wrong
+	  // way around.  Instead, the eh_frame code will discard
+	  // .eh_frame sections that refer to discarded sections.
+
 	  // Reading the symbols again here may be slow.
 	  Read_symbols_data sd;
 	  this->read_symbols(&sd);
@@ -1840,7 +1842,17 @@ Sized_relobj_file<size, big_endian>::do_
 					shdr,
 					deferred->reloc_shndx_,
 					deferred->reloc_type_);
+	  continue;
 	}
+
+      // If the section is not included, it is because the garbage collector
+      // decided it is not needed.  Avoid reverting that decision.
+      if (!this->is_section_included(deferred->shndx_))
+	continue;
+
+      this->layout_section(layout, deferred->shndx_, deferred->name_.c_str(),
+			   shdr, deferred->reloc_shndx_,
+			   deferred->reloc_type_);
     }
 
   this->deferred_layout_.clear();

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