GCC PR c++/56840
authorIan Lance Taylor <ian@airs.com>
Thu, 4 Apr 2013 16:49:04 +0000 (16:49 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 4 Apr 2013 16:49:04 +0000 (16:49 +0000)
* object.cc (do_layout_deferred_sections): Handle .eh_frame
sections before checking whether they are included in the link.

gold/ChangeLog
gold/object.cc

index 360599cfaf8ccce92b161bb5b11ed87e4fe00fd0..e1f8c4122f6dbdbed241e0c4ed1af1fd39ac3177 100644 (file)
@@ -1,3 +1,9 @@
+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.
+
 2013-03-29  Sriraman Tallam  <tmsriram@google.com>
 
        * archive.cc (Archive::get_elf_object_for_member):  Create the elf
index 34343031f8f11606c01b7a5474a43c1efa5bd3d2..715f7acd4a75fb25ad0305881397fc13c1d02cb0 100644 (file)
@@ -1815,19 +1815,21 @@ Sized_relobj_file<size, big_endian>::do_layout_deferred_sections(Layout* layout)
        ++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_layout_deferred_sections(Layout* layout)
                                        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();