diff options
-rw-r--r-- | gold/ChangeLog | 6 | ||||
-rw-r--r-- | gold/object.cc | 34 |
2 files changed, 29 insertions, 11 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 360599c..e1f8c41 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -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 diff --git a/gold/object.cc b/gold/object.cc index 3434303..715f7ac 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -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(); |