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]

PATCH COMMITTED: Fix mix of read-only/read-write .eh_frame sections


Normally gold does not combine read-only and read-write sections with
the same name.  This is different from GNU ld's behaviour.  However,
gcc relies on this merging when generating the .eh_frame section.  gcc
has a configure test for whether read-only and read-write sections are
merged; when they are merged, it emits read-only .eh_frame sections
when possible, read-write .eh-frame sections when necessary, in the
hopes that all the .eh_frame sections in a specific link will be
read-only.  Since existing gcc binaries have this behaviour, gold has
a special exception for merging read-only and read-write .eh_frame
sections.

However, this failed to correctly handle the case of an empty
read-write .eh_frame section.  Handling this case correctly is
required to make a static link work with some configurations of gcc.

I committed this patch to fix this.  Basically we just make sure that
we add the merge .eh_frame sections in the right place with respect to
unmerged .eh_frame sections.

Ian


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

	* layout.h (class Layout): Add added_eh_frame_data_ field.
	* layout.cc (Layout::Layout): Initialize new field.
	(Layout::layout_eh_frame): Don't add eh_frame_data_ to .eh_frame
	output section until we find a section we merged successfully.
	* object.cc (Sized_relobj::check_eh_frame_flags): Don't require
	that the size be non-zero.


Index: layout.h
===================================================================
RCS file: /cvs/src/src/gold/layout.h,v
retrieving revision 1.52
diff -u -p -r1.52 layout.h
--- layout.h	25 Mar 2008 05:11:41 -0000	1.52
+++ layout.h	9 Apr 2008 00:22:05 -0000
@@ -597,6 +597,8 @@ class Layout
   Output_section* eh_frame_section_;
   // The exception frame data for eh_frame_section_.
   Eh_frame* eh_frame_data_;
+  // Whether we have added eh_frame_data_ to the .eh_frame section.
+  bool added_eh_frame_data_;
   // The exception frame header output section if there is one.
   Output_section* eh_frame_hdr_section_;
   // The space for the build ID checksum if there is one.
Index: layout.cc
===================================================================
RCS file: /cvs/src/src/gold/layout.cc,v
retrieving revision 1.96
diff -u -p -r1.96 layout.cc
--- layout.cc	28 Mar 2008 22:42:34 -0000	1.96
+++ layout.cc	9 Apr 2008 00:22:05 -0000
@@ -82,7 +82,8 @@ Layout::Layout(const General_options& op
     unattached_section_list_(), special_output_list_(),
     section_headers_(NULL), tls_segment_(NULL), symtab_section_(NULL),
     dynsym_section_(NULL), dynamic_section_(NULL), dynamic_data_(NULL),
-    eh_frame_section_(NULL), eh_frame_data_(NULL), eh_frame_hdr_section_(NULL),
+    eh_frame_section_(NULL), eh_frame_data_(NULL),
+    added_eh_frame_data_(false), eh_frame_hdr_section_(NULL),
     build_id_note_(NULL), group_signatures_(), output_file_size_(-1),
     input_requires_executable_stack_(false),
     input_with_gnu_stack_note_(false),
@@ -563,7 +564,6 @@ Layout::layout_eh_frame(Sized_relobj<siz
     {
       this->eh_frame_section_ = os;
       this->eh_frame_data_ = new Eh_frame();
-      os->add_output_section_data(this->eh_frame_data_);
 
       if (this->options_.eh_frame_hdr())
 	{
@@ -605,7 +605,19 @@ Layout::layout_eh_frame(Sized_relobj<siz
 						      shndx,
 						      reloc_shndx,
 						      reloc_type))
-    *off = -1;
+    {
+      // 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;
+    }
   else
     {
       // We couldn't handle this .eh_frame section for some reason.
Index: object.cc
===================================================================
RCS file: /cvs/src/src/gold/object.cc,v
retrieving revision 1.66
diff -u -p -r1.66 object.cc
--- object.cc	2 Apr 2008 20:58:21 -0000	1.66
+++ object.cc	9 Apr 2008 00:22:05 -0000
@@ -226,8 +226,7 @@ bool
 Sized_relobj<size, big_endian>::check_eh_frame_flags(
     const elfcpp::Shdr<size, big_endian>* shdr) const
 {
-  return (shdr->get_sh_size() > 0
-	  && shdr->get_sh_type() == elfcpp::SHT_PROGBITS
+  return (shdr->get_sh_type() == elfcpp::SHT_PROGBITS
 	  && (shdr->get_sh_flags() & elfcpp::SHF_ALLOC) != 0);
 }
 

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