This is the mail archive of the binutils-cvs@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]

[binutils-gdb] Fix failure in exception_static_test.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e16631979e847a6b39db3435bea7708b9f34b36d

commit e16631979e847a6b39db3435bea7708b9f34b36d
Author: Cary Coutant <ccoutant@google.com>
Date:   Mon Mar 9 10:10:29 2015 -0700

    Fix failure in exception_static_test.
    
    Because the __EH_FRAME_BEGIN__ symbol is provided in an empty .eh_frame
    section in crtbeginT.o, if crt1.o has a non-empty .eh_frame section,
    we place all optimized .eh_frame sections into the output section ahead
    of the __EH_FRAME_BEGIN__ symbol, which breaks EH for statically-linked
    binaries.
    
    This patch fixes the problem by delaying the attachment of the optimized
    .eh_frame sections to the output section until we see the end marker
    section (or to the end of pass 1 if we never see an end marker).
    
    gold/
    	PR gold/14675
    	* ehframe.cc (Eh_frame::add_ehframe_input_section): Change return type;
    	return enum indicating whether .eh_frame section is empty, optimizable,
    	unrecognized, or an end marker. Adjust explicit instantiations.
    	* ehframe.h (Eh_frame::Eh_frame_section_disposition): New enum type.
    	(Eh_frame::add_ehframe_input_section): Change return type.
    	* gold.cc (queue_middle_tasks): Call Layout::finalize_eh_frame_section.
    	* layout.cc (Layout::layout_eh_frame): Don't add optimized sections
    	to the .eh_frame output section until we see the end marker.
    	(Layout::finalize_eh_frame_section): New.
    	* layout.h: (Layout::finalize_eh_frame_section): New.

Diff:
---
 gold/ChangeLog  | 14 ++++++++++
 gold/ehframe.cc | 18 ++++++-------
 gold/ehframe.h  | 10 +++++++-
 gold/gold.cc    |  3 +++
 gold/layout.cc  | 80 +++++++++++++++++++++++++++++++++++----------------------
 gold/layout.h   |  6 +++++
 6 files changed, 91 insertions(+), 40 deletions(-)

diff --git a/gold/ChangeLog b/gold/ChangeLog
index 24d3560..14a8610 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,17 @@
+2015-03-09  Cary Coutant  <ccoutant@google.com>
+
+	PR gold/14675
+	* ehframe.cc (Eh_frame::add_ehframe_input_section): Change return type;
+	return enum indicating whether .eh_frame section is empty, optimizable,
+	unrecognized, or an end marker. Adjust explicit instantiations.
+	* ehframe.h (Eh_frame::Eh_frame_section_disposition): New enum type.
+	(Eh_frame::add_ehframe_input_section): Change return type.
+	* gold.cc (queue_middle_tasks): Call Layout::finalize_eh_frame_section.
+	* layout.cc (Layout::layout_eh_frame): Don't add optimized sections
+	to the .eh_frame output section until we see the end marker.
+	(Layout::finalize_eh_frame_section): New.
+	* layout.h: (Layout::finalize_eh_frame_section): New.
+
 2015-03-05  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* output.cc (Relobj::initialize_input_to_output_map<size>):
diff --git a/gold/ehframe.cc b/gold/ehframe.cc
index 711103b..262766e 100644
--- a/gold/ehframe.cc
+++ b/gold/ehframe.cc
@@ -567,7 +567,7 @@ Eh_frame::skip_leb128(const unsigned char** pp, const unsigned char* pend)
 // section.
 
 template<int size, bool big_endian>
-bool
+Eh_frame::Eh_frame_section_disposition
 Eh_frame::add_ehframe_input_section(
     Sized_relobj_file<size, big_endian>* object,
     const unsigned char* symbols,
@@ -584,7 +584,7 @@ Eh_frame::add_ehframe_input_section(
 							    &contents_len,
 							    false);
   if (contents_len == 0)
-    return false;
+    return EH_EMPTY_SECTION;
 
   // If this is the marker section for the end of the data, then
   // return false to force it to be handled as an ordinary input
@@ -592,7 +592,7 @@ Eh_frame::add_ehframe_input_section(
   // of unrecognized .eh_frame sections.
   if (contents_len == 4
       && elfcpp::Swap<32, big_endian>::readval(pcontents) == 0)
-    return false;
+    return EH_END_MARKER_SECTION;
 
   New_cies new_cies;
   if (!this->do_add_ehframe_input_section(object, symbols, symbols_size,
@@ -609,7 +609,7 @@ Eh_frame::add_ehframe_input_section(
 	   ++p)
 	delete p->first;
 
-      return false;
+      return EH_UNRECOGNIZED_SECTION;
     }
 
   // Now that we know we are using this section, record any new CIEs
@@ -624,7 +624,7 @@ Eh_frame::add_ehframe_input_section(
 	this->unmergeable_cie_offsets_.push_back(p->first);
     }
 
-  return true;
+  return EH_OPTIMIZABLE_SECTION;
 }
 
 // The bulk of the implementation of add_ehframe_input_section.
@@ -1206,7 +1206,7 @@ Eh_frame::do_sized_write(unsigned char* oview)
 
 #ifdef HAVE_TARGET_32_LITTLE
 template
-bool
+Eh_frame::Eh_frame_section_disposition
 Eh_frame::add_ehframe_input_section<32, false>(
     Sized_relobj_file<32, false>* object,
     const unsigned char* symbols,
@@ -1220,7 +1220,7 @@ Eh_frame::add_ehframe_input_section<32, false>(
 
 #ifdef HAVE_TARGET_32_BIG
 template
-bool
+Eh_frame::Eh_frame_section_disposition
 Eh_frame::add_ehframe_input_section<32, true>(
     Sized_relobj_file<32, true>* object,
     const unsigned char* symbols,
@@ -1234,7 +1234,7 @@ Eh_frame::add_ehframe_input_section<32, true>(
 
 #ifdef HAVE_TARGET_64_LITTLE
 template
-bool
+Eh_frame::Eh_frame_section_disposition
 Eh_frame::add_ehframe_input_section<64, false>(
     Sized_relobj_file<64, false>* object,
     const unsigned char* symbols,
@@ -1248,7 +1248,7 @@ Eh_frame::add_ehframe_input_section<64, false>(
 
 #ifdef HAVE_TARGET_64_BIG
 template
-bool
+Eh_frame::Eh_frame_section_disposition
 Eh_frame::add_ehframe_input_section<64, true>(
     Sized_relobj_file<64, true>* object,
     const unsigned char* symbols,
diff --git a/gold/ehframe.h b/gold/ehframe.h
index bb47381..e6e21b2 100644
--- a/gold/ehframe.h
+++ b/gold/ehframe.h
@@ -359,6 +359,14 @@ extern bool operator==(const Cie&, const Cie&);
 class Eh_frame : public Output_section_data
 {
  public:
+  enum Eh_frame_section_disposition
+  {
+    EH_EMPTY_SECTION,
+    EH_UNRECOGNIZED_SECTION,
+    EH_OPTIMIZABLE_SECTION,
+    EH_END_MARKER_SECTION
+  };
+
   Eh_frame();
 
   // Record the associated Eh_frame_hdr, if any.
@@ -374,7 +382,7 @@ class Eh_frame : public Output_section_data
   // returns whether the section was incorporated into the .eh_frame
   // data.
   template<int size, bool big_endian>
-  bool
+  Eh_frame_section_disposition
   add_ehframe_input_section(Sized_relobj_file<size, big_endian>* object,
 			    const unsigned char* symbols,
 			    section_size_type symbols_size,
diff --git a/gold/gold.cc b/gold/gold.cc
index ab15980..e345887 100644
--- a/gold/gold.cc
+++ b/gold/gold.cc
@@ -492,6 +492,9 @@ queue_middle_tasks(const General_options& options,
   if (timer != NULL)
     timer->stamp(0);
 
+  // Finalize the .eh_frame section.
+  layout->finalize_eh_frame_section();
+
   // Add any symbols named with -u options to the symbol table.
   symtab->add_undefined_symbols_from_command_line(layout);
 
diff --git a/gold/layout.cc b/gold/layout.cc
index 7836640..14bfda0 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -1420,15 +1420,21 @@ Layout::layout_eh_frame(Sized_relobj_file<size, big_endian>* object,
 
   elfcpp::Elf_Xword orig_flags = os->flags();
 
-  if (!parameters->incremental()
-      && this->eh_frame_data_->add_ehframe_input_section(object,
-							 symbols,
-							 symbols_size,
-							 symbol_names,
-							 symbol_names_size,
-							 shndx,
-							 reloc_shndx,
-							 reloc_type))
+  Eh_frame::Eh_frame_section_disposition disp =
+      Eh_frame::EH_UNRECOGNIZED_SECTION;
+  if (!parameters->incremental())
+    {
+      disp = this->eh_frame_data_->add_ehframe_input_section(object,
+							     symbols,
+							     symbols_size,
+							     symbol_names,
+							     symbol_names_size,
+							     shndx,
+							     reloc_shndx,
+							     reloc_type);
+    }
+
+  if (disp == Eh_frame::EH_OPTIMIZABLE_SECTION)
     {
       os->update_flags_for_input_section(shdr.get_sh_flags());
 
@@ -1440,35 +1446,49 @@ Layout::layout_eh_frame(Sized_relobj_file<size, big_endian>* object,
 	  os->set_order(ORDER_RELRO);
 	}
 
-      // We found a .eh_frame section we are going to optimize, so now
-      // we can add the set of optimized sections to the output
-      // section.  We need to postpone adding this until we've found a
-      // section we can optimize so that the .eh_frame section in
-      // crtbegin.o winds up at the start of the output section.
-      if (!this->added_eh_frame_data_)
-	{
-	  os->add_output_section_data(this->eh_frame_data_);
-	  this->added_eh_frame_data_ = true;
-	}
       *off = -1;
+      return os;
     }
-  else
+
+  if (disp == Eh_frame::EH_END_MARKER_SECTION && !this->added_eh_frame_data_)
     {
-      // We couldn't handle this .eh_frame section for some reason.
-      // Add it as a normal section.
-      bool saw_sections_clause = this->script_options_->saw_sections_clause();
-      *off = os->add_input_section(this, object, shndx, ".eh_frame", shdr,
-				   reloc_shndx, saw_sections_clause);
-      this->have_added_input_section_ = true;
+      // We found the end marker section, so now we can add the set of
+      // optimized sections to the output section.  We need to postpone
+      // adding this until we've found a section we can optimize so that
+      // the .eh_frame section in crtbeginT.o winds up at the start of
+      // the output section.
+      os->add_output_section_data(this->eh_frame_data_);
+      this->added_eh_frame_data_ = true;
+     }
 
-      if ((orig_flags & (elfcpp::SHF_WRITE | elfcpp::SHF_EXECINSTR))
-	  != (os->flags() & (elfcpp::SHF_WRITE | elfcpp::SHF_EXECINSTR)))
-	os->set_order(this->default_section_order(os, false));
-    }
+  // We couldn't handle this .eh_frame section for some reason.
+  // Add it as a normal section.
+  bool saw_sections_clause = this->script_options_->saw_sections_clause();
+  *off = os->add_input_section(this, object, shndx, ".eh_frame", shdr,
+			       reloc_shndx, saw_sections_clause);
+  this->have_added_input_section_ = true;
+
+  if ((orig_flags & (elfcpp::SHF_WRITE | elfcpp::SHF_EXECINSTR))
+      != (os->flags() & (elfcpp::SHF_WRITE | elfcpp::SHF_EXECINSTR)))
+    os->set_order(this->default_section_order(os, false));
 
   return os;
 }
 
+void
+Layout::finalize_eh_frame_section()
+{
+  // If we never found an end marker section, we need to add the
+  // optimized eh sections to the output section now.
+  if (!parameters->incremental()
+      && this->eh_frame_section_ != NULL
+      && !this->added_eh_frame_data_)
+    {
+      this->eh_frame_section_->add_output_section_data(this->eh_frame_data_);
+      this->added_eh_frame_data_ = true;
+    }
+}
+
 // Create and return the magic .eh_frame section.  Create
 // .eh_frame_hdr also if appropriate.  OBJECT is the object with the
 // input .eh_frame section; it may be NULL.
diff --git a/gold/layout.h b/gold/layout.h
index aec0c53..9039ee8 100644
--- a/gold/layout.h
+++ b/gold/layout.h
@@ -635,6 +635,12 @@ class Layout
 		  unsigned int reloc_shndx, unsigned int reloc_type,
 		  off_t* offset);
 
+  // After processing all input files, we call this to make sure that
+  // the optimized .eh_frame sections have been added to the output
+  // section.
+  void
+  finalize_eh_frame_section();
+
   // Add .eh_frame information for a PLT.  The FDE must start with a
   // 4-byte PC-relative reference to the start of the PLT, followed by
   // a 4-byte size of PLT.


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