diff options
author | Ian Lance Taylor <ian@airs.com> | 2013-04-04 16:49:04 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2013-04-04 16:49:04 +0000 |
commit | 54a3d8656457344de2a89e8a88002662a105ecae (patch) | |
tree | 36ef6e10b60b5df6da26d54ed43debeb33b085b9 /gold | |
parent | e65cb106a6392c767895842229acbf90c5510077 (diff) | |
download | binutils-54a3d8656457344de2a89e8a88002662a105ecae.zip binutils-54a3d8656457344de2a89e8a88002662a105ecae.tar.gz binutils-54a3d8656457344de2a89e8a88002662a105ecae.tar.bz2 |
GCC PR c++/56840
* object.cc (do_layout_deferred_sections): Handle .eh_frame
sections before checking whether they are included in the link.
Diffstat (limited to 'gold')
-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(); |