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 | 1f6a3650a82238c09a5a78c962f1087e1f52aac1 (patch) | |
tree | 6579f0493bfdc950e19429cb0b8f127a413e510f /gold | |
parent | c8349dfa1e4cbcd047f2c8731570f8a700ecded8 (diff) | |
download | binutils-redhat-1f6a3650a82238c09a5a78c962f1087e1f52aac1.tar.gz |
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 360599cfaf..e1f8c4122f 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 34343031f8..715f7acd4a 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(); |