* layout.h (class Layout): Add added_eh_frame_data_ field.
authorIan Lance Taylor <ian@airs.com>
Wed, 9 Apr 2008 00:26:48 +0000 (00:26 +0000)
committerIan Lance Taylor <ian@airs.com>
Wed, 9 Apr 2008 00:26:48 +0000 (00:26 +0000)
* 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.

gold/ChangeLog
gold/layout.cc
gold/layout.h
gold/object.cc

index 6a8ac989145953afb5f1252a7c6e18ef19a37b6d..78ff07e83c4f323de4087902b66a99f3584c3052 100644 (file)
@@ -1,5 +1,12 @@
 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.
+
        * merge.cc (Object_merge_map::get_output_offset): Remove inline
        qualifier.
 
index e8582ca7a9ade548fb33a629feea072700eac94d..efeaf659a4d7a7026c258fcc1793585b7234530c 100644 (file)
@@ -82,7 +82,8 @@ Layout::Layout(const General_options& options, Script_options* script_options)
     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<size, big_endian>* object,
     {
       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<size, big_endian>* object,
                                                      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 fe888c7786dd7e16ceb8b9ea15316ec5f0714266..edf64382ddb3c45a4638784315d9028a6adc8c52 100644 (file)
@@ -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 c1ddae4c4b214c755b26d74a1725793983a138d9..36d3dcc874d315d86ebdc1030377c85033c4cf86 100644 (file)
@@ -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);
 }