aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2013-04-04 16:49:04 +0000
committerIan Lance Taylor <ian@airs.com>2013-04-04 16:49:04 +0000
commit54a3d8656457344de2a89e8a88002662a105ecae (patch)
tree36ef6e10b60b5df6da26d54ed43debeb33b085b9 /gold
parente65cb106a6392c767895842229acbf90c5510077 (diff)
downloadbinutils-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/ChangeLog6
-rw-r--r--gold/object.cc34
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();