This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH COMMITTED: Fix mix of read-only/read-write .eh_frame sections
- From: Ian Lance Taylor <iant at google dot com>
- To: binutils at sourceware dot org
- Date: Tue, 08 Apr 2008 17:32:07 -0700
- Subject: PATCH COMMITTED: Fix mix of read-only/read-write .eh_frame sections
Normally gold does not combine read-only and read-write sections with
the same name. This is different from GNU ld's behaviour. However,
gcc relies on this merging when generating the .eh_frame section. gcc
has a configure test for whether read-only and read-write sections are
merged; when they are merged, it emits read-only .eh_frame sections
when possible, read-write .eh-frame sections when necessary, in the
hopes that all the .eh_frame sections in a specific link will be
read-only. Since existing gcc binaries have this behaviour, gold has
a special exception for merging read-only and read-write .eh_frame
sections.
However, this failed to correctly handle the case of an empty
read-write .eh_frame section. Handling this case correctly is
required to make a static link work with some configurations of gcc.
I committed this patch to fix this. Basically we just make sure that
we add the merge .eh_frame sections in the right place with respect to
unmerged .eh_frame sections.
Ian
2008-04-08 Ian Lance Taylor <iant@google.com>
* layout.h (class Layout): Add added_eh_frame_data_ field.
* layout.cc (Layout::Layout): Initialize new field.
(Layout::layout_eh_frame): Don't add eh_frame_data_ to .eh_frame
output section until we find a section we merged successfully.
* object.cc (Sized_relobj::check_eh_frame_flags): Don't require
that the size be non-zero.
Index: layout.h
===================================================================
RCS file: /cvs/src/src/gold/layout.h,v
retrieving revision 1.52
diff -u -p -r1.52 layout.h
--- layout.h 25 Mar 2008 05:11:41 -0000 1.52
+++ layout.h 9 Apr 2008 00:22:05 -0000
@@ -597,6 +597,8 @@ class Layout
Output_section* eh_frame_section_;
// The exception frame data for eh_frame_section_.
Eh_frame* eh_frame_data_;
+ // Whether we have added eh_frame_data_ to the .eh_frame section.
+ bool added_eh_frame_data_;
// The exception frame header output section if there is one.
Output_section* eh_frame_hdr_section_;
// The space for the build ID checksum if there is one.
Index: layout.cc
===================================================================
RCS file: /cvs/src/src/gold/layout.cc,v
retrieving revision 1.96
diff -u -p -r1.96 layout.cc
--- layout.cc 28 Mar 2008 22:42:34 -0000 1.96
+++ layout.cc 9 Apr 2008 00:22:05 -0000
@@ -82,7 +82,8 @@ Layout::Layout(const General_options& op
unattached_section_list_(), special_output_list_(),
section_headers_(NULL), tls_segment_(NULL), symtab_section_(NULL),
dynsym_section_(NULL), dynamic_section_(NULL), dynamic_data_(NULL),
- eh_frame_section_(NULL), eh_frame_data_(NULL), eh_frame_hdr_section_(NULL),
+ eh_frame_section_(NULL), eh_frame_data_(NULL),
+ added_eh_frame_data_(false), eh_frame_hdr_section_(NULL),
build_id_note_(NULL), group_signatures_(), output_file_size_(-1),
input_requires_executable_stack_(false),
input_with_gnu_stack_note_(false),
@@ -563,7 +564,6 @@ Layout::layout_eh_frame(Sized_relobj<siz
{
this->eh_frame_section_ = os;
this->eh_frame_data_ = new Eh_frame();
- os->add_output_section_data(this->eh_frame_data_);
if (this->options_.eh_frame_hdr())
{
@@ -605,7 +605,19 @@ Layout::layout_eh_frame(Sized_relobj<siz
shndx,
reloc_shndx,
reloc_type))
- *off = -1;
+ {
+ // We found a .eh_frame section we are going to optimize, so now
+ // we can add the set of optimized sections to the output
+ // section. We need to postpone adding this until we've found a
+ // section we can optimize so that the .eh_frame section in
+ // crtbegin.o winds up at the start of the output section.
+ if (!this->added_eh_frame_data_)
+ {
+ os->add_output_section_data(this->eh_frame_data_);
+ this->added_eh_frame_data_ = true;
+ }
+ *off = -1;
+ }
else
{
// We couldn't handle this .eh_frame section for some reason.
Index: object.cc
===================================================================
RCS file: /cvs/src/src/gold/object.cc,v
retrieving revision 1.66
diff -u -p -r1.66 object.cc
--- object.cc 2 Apr 2008 20:58:21 -0000 1.66
+++ object.cc 9 Apr 2008 00:22:05 -0000
@@ -226,8 +226,7 @@ bool
Sized_relobj<size, big_endian>::check_eh_frame_flags(
const elfcpp::Shdr<size, big_endian>* shdr) const
{
- return (shdr->get_sh_size() > 0
- && shdr->get_sh_type() == elfcpp::SHT_PROGBITS
+ return (shdr->get_sh_type() == elfcpp::SHT_PROGBITS
&& (shdr->get_sh_flags() & elfcpp::SHF_ALLOC) != 0);
}