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: Fix .eh_frame sections when using plugins


When using plugins, section layout is deferred for objects following a
claimed object.  Unfortunately, .eh_frame section layout was not being
deferred.  This matters when it comes to handling crtend.o.  This lead
to the poor debugging experience described in PR 12629.  This patch
fixes the problem by deferring the layout of .eh_frame sections when
appropriate.  Committed to mainline.

Ian


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

	PR gold/12629
	* object.cc (Sized_relobj_file::layout_section): Change shdr
	parameter to be const.
	(Sized_relobj_file::layout_eh_frame_section): New function, broken
	out of do_layout.
	(Sized_relobj_file::do_layout): Defer .eh_frame sections if
	appropriate.  Call layout_eh_frame_section.
	(Sized_relobj_file::do_layout_deferred_sections): Handle .eh_frame
	sections.
	* object.h (class Sized_relobj_file): Update declarations.


Index: object.cc
===================================================================
RCS file: /cvs/src/src/gold/object.cc,v
retrieving revision 1.144
diff -u -p -r1.144 object.cc
--- object.cc	29 Jun 2011 21:39:19 -0000	1.144
+++ object.cc	30 Jun 2011 00:47:23 -0000
@@ -1018,12 +1018,13 @@ Sized_relobj_file<size, big_endian>::inc
 
 template<int size, bool big_endian>
 inline void
-Sized_relobj_file<size, big_endian>::layout_section(Layout* layout,
-						    unsigned int shndx,
-						    const char* name,
-						    typename This::Shdr& shdr,
-						    unsigned int reloc_shndx,
-						    unsigned int reloc_type)
+Sized_relobj_file<size, big_endian>::layout_section(
+    Layout* layout,
+    unsigned int shndx,
+    const char* name,
+    const typename This::Shdr& shdr,
+    unsigned int reloc_shndx,
+    unsigned int reloc_type)
 {
   off_t offset;
   Output_section* os = layout->layout(this, shndx, name, shdr,
@@ -1042,6 +1043,53 @@ Sized_relobj_file<size, big_endian>::lay
     this->set_relocs_must_follow_section_writes();
 }
 
+// Layout an input .eh_frame section.
+
+template<int size, bool big_endian>
+void
+Sized_relobj_file<size, big_endian>::layout_eh_frame_section(
+    Layout* layout,
+    const unsigned char* symbols_data,
+    section_size_type symbols_size,
+    const unsigned char* symbol_names_data,
+    section_size_type symbol_names_size,
+    unsigned int shndx,
+    const typename This::Shdr& shdr,
+    unsigned int reloc_shndx,
+    unsigned int reloc_type)
+{
+  gold_assert(this->has_eh_frame_);
+
+  off_t offset;
+  Output_section* os = layout->layout_eh_frame(this,
+					       symbols_data,
+					       symbols_size,
+					       symbol_names_data,
+					       symbol_names_size,
+					       shndx,
+					       shdr,
+					       reloc_shndx,
+					       reloc_type,
+					       &offset);
+  this->output_sections()[shndx] = os;
+  if (os == NULL || offset == -1)
+    {
+      // An object can contain at most one section holding exception
+      // frame information.
+      gold_assert(this->discarded_eh_frame_shndx_ == -1U);
+      this->discarded_eh_frame_shndx_ = shndx;
+      this->section_offsets()[shndx] = invalid_address;
+    }
+  else
+    this->section_offsets()[shndx] = convert_types<Address, off_t>(offset);
+
+  // If this section requires special handling, and if there are
+  // relocs that aply to it, then we must do the special handling
+  // before we apply the relocs.
+  if (os != NULL && offset == -1 && reloc_shndx != 0)
+    this->set_relocs_must_follow_section_writes();
+}
+
 // Lay out the input sections.  We walk through the sections and check
 // whether they should be included in the link.  If they should, we
 // pass them to the Layout object, which will return an output section
@@ -1367,7 +1415,12 @@ Sized_relobj_file<size, big_endian>::do_
               out_sections[i] = reinterpret_cast<Output_section*>(1);
               out_section_offsets[i] = invalid_address;
             }
-          else
+          else if (should_defer_layout)
+	    this->deferred_layout_.push_back(Deferred_layout(i, name,
+							     pshdrs,
+							     reloc_shndx[i],
+							     reloc_type[i]));
+	  else
             eh_frame_sections.push_back(i);
           continue;
         }
@@ -1527,7 +1580,6 @@ Sized_relobj_file<size, big_endian>::do_
        p != eh_frame_sections.end();
        ++p)
     {
-      gold_assert(this->has_eh_frame_);
       gold_assert(external_symbols_offset != 0);
 
       unsigned int i = *p;
@@ -1535,33 +1587,15 @@ Sized_relobj_file<size, big_endian>::do_
       pshdr = section_headers_data + i * This::shdr_size;
       typename This::Shdr shdr(pshdr);
 
-      off_t offset;
-      Output_section* os = layout->layout_eh_frame(this,
-						   symbols_data,
-						   symbols_size,
-						   symbol_names_data,
-						   symbol_names_size,
-						   i, shdr,
-						   reloc_shndx[i],
-						   reloc_type[i],
-						   &offset);
-      out_sections[i] = os;
-      if (os == NULL || offset == -1)
-	{
-	  // An object can contain at most one section holding exception
-	  // frame information.
-	  gold_assert(this->discarded_eh_frame_shndx_ == -1U);
-	  this->discarded_eh_frame_shndx_ = i;
-	  out_section_offsets[i] = invalid_address;
-	}
-      else
-        out_section_offsets[i] = convert_types<Address, off_t>(offset);
-
-      // If this section requires special handling, and if there are
-      // relocs that apply to it, then we must do the special handling
-      // before we apply the relocs.
-      if (os != NULL && offset == -1 && reloc_shndx[i] != 0)
-	this->set_relocs_must_follow_section_writes();
+      this->layout_eh_frame_section(layout,
+				    symbols_data,
+				    symbols_size,
+				    symbol_names_data,
+				    symbol_names_size,
+				    i,
+				    shdr,
+				    reloc_shndx[i],
+				    reloc_type[i]);
     }
 
   if (is_gc_pass_two)
@@ -1600,8 +1634,27 @@ Sized_relobj_file<size, big_endian>::do_
       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_);
+      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
+	{
+	  // Reading the symbols again here may be slow.
+	  Read_symbols_data sd;
+	  this->read_symbols(&sd);
+	  this->layout_eh_frame_section(layout,
+					sd.symbols->data(),
+					sd.symbols_size,
+					sd.symbol_names->data(),
+					sd.symbol_names_size,
+					deferred->shndx_,
+					shdr,
+					deferred->reloc_shndx_,
+					deferred->reloc_type_);
+	}
     }
 
   this->deferred_layout_.clear();
Index: object.h
===================================================================
RCS file: /cvs/src/src/gold/object.h,v
retrieving revision 1.111
diff -u -p -r1.111 object.h
--- object.h	25 Jun 2011 00:40:56 -0000	1.111
+++ object.h	30 Jun 2011 00:47:23 -0000
@@ -2306,9 +2306,18 @@ class Sized_relobj_file : public Sized_r
   // Layout an input section.
   void
   layout_section(Layout* layout, unsigned int shndx, const char* name,
-                 typename This::Shdr& shdr, unsigned int reloc_shndx,
+                 const typename This::Shdr& shdr, unsigned int reloc_shndx,
                  unsigned int reloc_type);
 
+  // Layout an input .eh_frame section.
+  void
+  layout_eh_frame_section(Layout* layout, const unsigned char* symbols_data,
+			  section_size_type symbols_size,
+			  const unsigned char* symbol_names_data,
+			  section_size_type symbol_names_size,
+			  unsigned int shndx, const typename This::Shdr&,
+			  unsigned int reloc_shndx, unsigned int reloc_type);
+
   // Write section data to the output file.  Record the views and
   // sizes in VIEWS for use when relocating.
   void

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