This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
gold patch committed: Don't check discarded deferred .eh_frame section
- From: Ian Lance Taylor <iant at google dot com>
- To: binutils at sourceware dot org
- Date: Thu, 04 Apr 2013 09:49:07 -0700
- Subject: gold patch committed: Don't check discarded deferred .eh_frame section
The code that handles deferred .eh_frame sections when using a plugin
had a bug: it checked whether the section was included in the link
before doing the .eh_frame handling. Unfortunately, the check for an
included section always indicates that a .eh_frame section is not
included, because .eh_frame sections are handled specially. This led to
http://gcc.gnu.org/PR56840 , in which .eh_frame sections in archives are
discarded inappropriately.
This patch fixes the problem. Committed to mainline.
Ian
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.
Index: object.cc
===================================================================
RCS file: /cvs/src/src/gold/object.cc,v
retrieving revision 1.162
diff -u -p -r1.162 object.cc
--- object.cc 10 Mar 2013 23:08:18 -0000 1.162
+++ object.cc 4 Apr 2013 16:43:41 -0000
@@ -1815,19 +1815,21 @@ Sized_relobj_file<size, big_endian>::do_
++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_
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();