This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
PATCH: PR gold/14675: No eh_frame info registered in exception_static_test
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: Ian Lance Taylor <iant at google dot com>
- Cc: Roland McGrath <roland at hack dot frob dot com>, Cary Coutant <ccoutant at google dot com>, Alan Modra <amodra at gmail dot com>, "GNU C. Library" <libc-alpha at sourceware dot org>, Binutils <binutils at sourceware dot org>, Rafael Ávila de Espíndola <rafael dot espindola at gmail dot com>
- Date: Sat, 20 Dec 2014 05:58:11 -0800
- Subject: PATCH: PR gold/14675: No eh_frame info registered in exception_static_test
- Authentication-results: sourceware.org; auth=none
- References: <20140330045552 dot GX18201 at bubble dot grove dot modra dot org> <20140330050615 dot 7DC5774481 at topped-with-meat dot com> <CAKOQZ8wPgdHfA9QJWQ9yVO9gVQKL=HF-rpuipCBxzsx3=TcqwA at mail dot gmail dot com> <20140331200446 dot A09B074430 at topped-with-meat dot com> <CAKOQZ8x19YZ_oyJXyxe9JST4nfaG8dDvVrdf-vmgkNWydrpsrw at mail dot gmail dot com> <20140331214025 dot E61517447E at topped-with-meat dot com> <CAKOQZ8x1W0YxJSq+X74EjMj7_02uTZq82qzhmF=oQ-cTd4S1mQ at mail dot gmail dot com> <CAHACq4oRKDGKAUu3octDCxKg2EueCyf8kHWj0t8g9+LmE3JagQ at mail dot gmail dot com> <20140910225238 dot 0B6362C39CF at topped-with-meat dot com> <CAKOQZ8zW_zbR1Tog6HWak9T4d9gXMd9iK=PenQq2E5u-kiNr6Q at mail dot gmail dot com>
On Wed, Sep 10, 2014 at 05:04:41PM -0700, Ian Lance Taylor wrote:
> On Wed, Sep 10, 2014 at 3:52 PM, Roland McGrath <roland@hack.frob.com> wrote:
> >
> > Incidentally, Ian mentioned Gold having had a special case for the
> > __EH_FRAME_BEGIN__ symbol. But 'git log -G__EH_FRAME_BEGIN -- gold' finds
> > no point in the history where Gold's source code mentioned that symbol. Do
> > you know what Ian was referring to? From
> > https://sourceware.org/ml/libc-alpha/2014-04/msg00021.html:
> >
> > I freely grant that GCC's crtbegin.o file tries this trick in a number
> > of different ways--even worse, crtend.o has trailing symbols. Because
> > of this existing behaviour, gold has various special cases to make it
> > continue to work. One of those special cases is for
> > __EH_FRAME_BEGIN__. As you've seen, the existing special case does
> > not work any more. This is an unfortunate interaction. I don't think
> > it's an obvious bug.
>
> I shouldn't have said __EH_FRAME_BEGIN__. There is no special case
> for the symbol. There is a special case for the sections found in
> typical crtbegin/crtend files. It's these lines in
> Eh_frame::add_ehframe_input_section in gold/ehframe.cc:
>
> if (contents_len == 0)
> return false;
>
> // If this is the marker section for the end of the data, then
> // return false to force it to be handled as an ordinary input
> // section. If we don't do this, we won't correctly handle the case
> // of unrecognized .eh_frame sections.
> if (contents_len == 4
> && elfcpp::Swap<32, big_endian>::readval(pcontents) == 0)
> return false;
>
> Ian
Here is an idea. Does it look OK?
Thanks.
H.J.
---
>From 4a5d5d94ca76cbf730d7f0379601e75f9469670e Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Sat, 20 Dec 2014 05:45:51 -0800
Subject: [PATCH] Treat .eh_frame section before crtbegin as normal input
Force the exception frame section from input files before the crtbegin
file to be handled as an ordinary input section if we aren't creating
the exception frame header. If we don't do this, we won't correctly
handle the special marker symbol in the exception frame section in the
crtbegin file.
PR gold/14675
* ehframe.cc (Eh_frame::add_ehframe_input_section): Force the
exception frame section from input files before the crtbegin
file to be handled as an ordinary input section if we aren't
creating the exception frame header.
(Eh_frame::add_ehframe_input_section<32, false>): Updated.
(Eh_frame::add_ehframe_input_section<32, true>): Likewise.
(Eh_frame::add_ehframe_input_section<64, false>): Likewise.
(Eh_frame::add_ehframe_input_section<64, true>): Likewise.
* ehframe.h (Eh_frame::add_ehframe_input_section): Add a
bool parameter to indicate if the crtbegin file has been
processed.
* layout.cc (Layout::Layout): Initialize seen_crtbegin_.
(Layout::layout_eh_frame): Pass this->seen_crtbegin_ to
Eh_frame::add_ehframe_input_section.
(Layout::make_eh_frame_section): Set this->seen_crtbegin_ to
true when processing the crtbegin file.
* layout.h (Layout): Add a seen_crtbegin_ field.
---
gold/ChangeLog | 21 +++++++++++++++++++++
gold/ehframe.cc | 34 ++++++++++++++++++++++++----------
gold/ehframe.h | 6 ++++--
gold/layout.cc | 10 +++++++++-
gold/layout.h | 3 +++
5 files changed, 61 insertions(+), 13 deletions(-)
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 9edf043..9cd3f8f 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,24 @@
+2014-12-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR gold/14675
+ * ehframe.cc (Eh_frame::add_ehframe_input_section): Force the
+ exception frame section from input files before the crtbegin
+ file to be handled as an ordinary input section if we aren't
+ creating the exception frame header.
+ (Eh_frame::add_ehframe_input_section<32, false>): Updated.
+ (Eh_frame::add_ehframe_input_section<32, true>): Likewise.
+ (Eh_frame::add_ehframe_input_section<64, false>): Likewise.
+ (Eh_frame::add_ehframe_input_section<64, true>): Likewise.
+ * ehframe.h (Eh_frame::add_ehframe_input_section): Add a
+ bool parameter to indicate if the crtbegin file has been
+ processed.
+ * layout.cc (Layout::Layout): Initialize seen_crtbegin_.
+ (Layout::layout_eh_frame): Pass this->seen_crtbegin_ to
+ Eh_frame::add_ehframe_input_section.
+ (Layout::make_eh_frame_section): Set this->seen_crtbegin_ to
+ true when processing the crtbegin file.
+ * layout.h (Layout): Add a seen_crtbegin_ field.
+
2014-12-16 Cary Coutant <ccoutant@google.com>
* mapfile.cc (Mapfile::print_input_section): Print uncompressed sizes.
diff --git a/gold/ehframe.cc b/gold/ehframe.cc
index c711bac..dde90df 100644
--- a/gold/ehframe.cc
+++ b/gold/ehframe.cc
@@ -576,7 +576,8 @@ Eh_frame::add_ehframe_input_section(
section_size_type symbol_names_size,
unsigned int shndx,
unsigned int reloc_shndx,
- unsigned int reloc_type)
+ unsigned int reloc_type,
+ bool crtbegin_seen)
{
// Get the section contents.
section_size_type contents_len;
@@ -595,15 +596,24 @@ Eh_frame::add_ehframe_input_section(
return false;
New_cies new_cies;
- if (!this->do_add_ehframe_input_section(object, symbols, symbols_size,
+ bool recognized_eh_frame_section
+ = this->do_add_ehframe_input_section(object, symbols, symbols_size,
symbol_names, symbol_names_size,
shndx, reloc_shndx,
reloc_type, pcontents,
- contents_len, &new_cies))
+ contents_len, &new_cies);
+ if (!recognized_eh_frame_section && this->eh_frame_hdr_ != NULL)
+ this->eh_frame_hdr_->found_unrecognized_eh_frame_section();
+
+ // If we don't unrecognize the exception frame section or we haven't
+ // seen the crtbegin file and we aren't creating the exception frame
+ // header, then return false to force it to be handled as an ordinary
+ // input section. If we don't do this, we won't correctly handle the
+ // special marker symbol in the exception frame section in the crtbegin
+ // file.
+ if (!recognized_eh_frame_section
+ || (this->eh_frame_hdr_ == NULL && !crtbegin_seen))
{
- if (this->eh_frame_hdr_ != NULL)
- this->eh_frame_hdr_->found_unrecognized_eh_frame_section();
-
for (New_cies::iterator p = new_cies.begin();
p != new_cies.end();
++p)
@@ -1224,7 +1234,8 @@ Eh_frame::add_ehframe_input_section<32, false>(
section_size_type symbol_names_size,
unsigned int shndx,
unsigned int reloc_shndx,
- unsigned int reloc_type);
+ unsigned int reloc_type,
+ bool crtbegin_seen);
#endif
#ifdef HAVE_TARGET_32_BIG
@@ -1238,7 +1249,8 @@ Eh_frame::add_ehframe_input_section<32, true>(
section_size_type symbol_names_size,
unsigned int shndx,
unsigned int reloc_shndx,
- unsigned int reloc_type);
+ unsigned int reloc_type,
+ bool crtbegin_seen);
#endif
#ifdef HAVE_TARGET_64_LITTLE
@@ -1252,7 +1264,8 @@ Eh_frame::add_ehframe_input_section<64, false>(
section_size_type symbol_names_size,
unsigned int shndx,
unsigned int reloc_shndx,
- unsigned int reloc_type);
+ unsigned int reloc_type,
+ bool crtbegin_seen);
#endif
#ifdef HAVE_TARGET_64_BIG
@@ -1266,7 +1279,8 @@ Eh_frame::add_ehframe_input_section<64, true>(
section_size_type symbol_names_size,
unsigned int shndx,
unsigned int reloc_shndx,
- unsigned int reloc_type);
+ unsigned int reloc_type,
+ bool crtbegin_seen);
#endif
} // End namespace gold.
diff --git a/gold/ehframe.h b/gold/ehframe.h
index 2ae12e0..b0effa0 100644
--- a/gold/ehframe.h
+++ b/gold/ehframe.h
@@ -371,7 +371,8 @@ class Eh_frame : public Output_section_data
// is the relocation section if any (0 for none, -1U for multiple).
// RELOC_TYPE is the type of the relocation section if any. This
// returns whether the section was incorporated into the .eh_frame
- // data.
+ // data. CRTBEGIN_SEEN is true if the crtbegin file has been
+ // processed.
template<int size, bool big_endian>
bool
add_ehframe_input_section(Sized_relobj_file<size, big_endian>* object,
@@ -380,7 +381,8 @@ class Eh_frame : public Output_section_data
const unsigned char* symbol_names,
section_size_type symbol_names_size,
unsigned int shndx, unsigned int reloc_shndx,
- unsigned int reloc_type);
+ unsigned int reloc_type,
+ bool crtbegin_seen);
// Add a CIE and an FDE for a PLT section, to permit unwinding
// through a PLT. The FDE data should start with 8 bytes of zero,
diff --git a/gold/layout.cc b/gold/layout.cc
index 0a71a2a..6649f9f 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -469,6 +469,7 @@ Layout::Layout(int number_of_input_files, Script_options* script_options)
unique_segment_for_sections_specified_(false),
incremental_inputs_(NULL),
record_output_section_data_from_script_(false),
+ seen_crtbegin_(false),
script_output_section_data_list_(),
segment_states_(NULL),
relaxation_debug_check_(NULL),
@@ -1428,7 +1429,8 @@ Layout::layout_eh_frame(Sized_relobj_file<size, big_endian>* object,
symbol_names_size,
shndx,
reloc_shndx,
- reloc_type))
+ reloc_type,
+ this->seen_crtbegin_))
{
os->update_flags_for_input_section(shdr.get_sh_flags());
@@ -1485,6 +1487,12 @@ Layout::make_eh_frame_section(const Relobj* object)
if (os == NULL)
return NULL;
+ if (object != NULL && Layout::match_file_name(object, "crtbegin"))
+ {
+ gold_assert(!this->seen_crtbegin_);
+ this->seen_crtbegin_ = true;
+ }
+
if (this->eh_frame_section_ == NULL)
{
this->eh_frame_section_ = os;
diff --git a/gold/layout.h b/gold/layout.h
index 032f5f3..74e5ec1 100644
--- a/gold/layout.h
+++ b/gold/layout.h
@@ -1420,6 +1420,9 @@ class Layout
Incremental_inputs* incremental_inputs_;
// Whether we record output section data created in script
bool record_output_section_data_from_script_;
+ // Whether we have seen the crtbegin file when processing the exception
+ // frame sections.
+ bool seen_crtbegin_;
// List of output data that needs to be removed at relaxation clean up.
Output_section_data_list script_output_section_data_list_;
// Structure to save segment states before entering the relaxation loop.
--
1.9.3