This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: 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: Cary Coutant <ccoutant at google dot com>
- Cc: Ian Lance Taylor <iant at google dot com>, Roland McGrath <roland at hack dot frob 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: Mon, 22 Dec 2014 16:58:05 -0800
- Subject: Re: 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> <20141220135811 dot GA7161 at gmail dot com> <CAHACq4r6f_dGg5fB=mcrdcQMHcERRVnTBVyJTSrh8YTsWCNTBQ at mail dot gmail dot com> <CAMe9rOrB9wXVnzbCCwK3hkSBsOxY=oaA1XSnhmfuoryG=9tBdg at mail dot gmail dot com>
On Mon, Dec 22, 2014 at 2:40 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Mon, Dec 22, 2014 at 9:37 AM, Cary Coutant <ccoutant@google.com> wrote:
>>> Here is an idea. Does it look OK?
>>
>> I don't like the idea of making a file named "crtbegin" magic, and
>> with this patch, any link *without* such a file will no longer
>> optimize eh data.
>>
>> -cary
>
> How about this? We do this only when there is a crtbeginT file
> on command line?
>
> --
> H.J.
> ---
> PR gold/14675
> * ehframe.cc (Eh_frame::add_ehframe_input_section): Force the
> exception frame section from input files if it can't be
> optimized.
> (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 exception frame section
> can be optimized.
> * layout.cc (Layout::Layout): Initialize has_crtbeginT_ to
> has_crtbeginT and optimize_ehframe_ to !has_crtbeginT.
> (Layout::layout_eh_frame): Pass this->optimize_ehframe_ to
> Eh_frame::add_ehframe_input_section.
> (Layout::make_eh_frame_section): Set this->optimize_ehframe_
> to true when processing the crtbeginT file if it is on command
> line.
> (Layout::match_file_name (const char*, const char*)): New.
> (Layout::match_file_name(const Relobj*, const char*): Use it.
> * layout.h (Layout::Layout): Add has_crtbeginT.
> (Layout::match_file_name (const char*, const char*)): New.
> (Layout): Add has_crtbeginT_ and optimize_ehframe_ members.
> * main.cc (main): Update layout.
> * options.cc (Input_arguments::add_file): Set
> this->has_crtbeginT_ to true if there is a crtbeginT file.
> * options.h (Input_arguments::Input_arguments): Initialize
> has_crtbeginT_.
> (Input_arguments::has_crtbeginT): New function.
> (Input_arguments::has_crtbeginT_): New bool member.
> (Command_line::crtbeginT): New function.
Slightly updated patch. We don't need to add a has_crtbeginT_
member to Layout. optimize_ehframe_ is sufficient.
--
H.J.
From cade3c669933278d78d5a8900458324aadd68b14 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 crtbeginT as normal input
Force the exception frame section from input files before the crtbeginT
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
crtbeginT file.
PR gold/14675
* ehframe.cc (Eh_frame::add_ehframe_input_section): Force the
exception frame section from input files if it can't be
optimized.
(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 exception frame section
can be optimized.
* layout.cc (Layout::Layout): Initialize optimize_ehframe_ to
!has_crtbeginT.
(Layout::layout_eh_frame): Pass this->optimize_ehframe_ to
Eh_frame::add_ehframe_input_section.
(Layout::make_eh_frame_section): Set this->optimize_ehframe_
to true when processing the crtbeginT file if it is on command
line.
(Layout::match_file_name (const char*, const char*)): New.
(Layout::match_file_name(const Relobj*, const char*): Use it.
* layout.h (Layout::Layout): Add has_crtbeginT.
(Layout::match_file_name (const char*, const char*)): New.
(Layout): Add an optimize_ehframe_ member.
* main.cc (main): Update layout.
* options.cc: Include "layout.h".
(Input_arguments::add_file): Set this->has_crtbeginT_ to true
if there is a crtbeginT file.
* options.h (Input_arguments::Input_arguments): Initialize
has_crtbeginT_ to false.
(Input_arguments::has_crtbeginT): New function.
(Input_arguments::has_crtbeginT_): New bool member.
(Command_line::crtbeginT): New function.
---
gold/ChangeLog | 35 +++++++++++++++++++++++++++++++++++
gold/ehframe.cc | 31 +++++++++++++++++++++----------
gold/ehframe.h | 6 ++++--
gold/layout.cc | 37 +++++++++++++++++++++++++++++--------
gold/layout.h | 10 +++++++++-
gold/main.cc | 3 ++-
gold/options.cc | 4 ++++
gold/options.h | 15 ++++++++++++++-
8 files changed, 118 insertions(+), 23 deletions(-)
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 457fa6b..ee56b98 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,38 @@
+2014-12-22 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 if it can't be
+ optimized.
+ (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 exception frame section
+ can be optimized.
+ * layout.cc (Layout::Layout): Initialize optimize_ehframe_ to
+ !has_crtbeginT.
+ (Layout::layout_eh_frame): Pass this->optimize_ehframe_ to
+ Eh_frame::add_ehframe_input_section.
+ (Layout::make_eh_frame_section): Set this->optimize_ehframe_
+ to true when processing the crtbeginT file if it is on command
+ line.
+ (Layout::match_file_name (const char*, const char*)): New.
+ (Layout::match_file_name(const Relobj*, const char*): Use it.
+ * layout.h (Layout::Layout): Add has_crtbeginT.
+ (Layout::match_file_name (const char*, const char*)): New.
+ (Layout): Add an optimize_ehframe_ member.
+ * main.cc (main): Update layout.
+ * options.cc: Include "layout.h".
+ (Input_arguments::add_file): Set this->has_crtbeginT_ to true
+ if there is a crtbeginT file.
+ * options.h (Input_arguments::Input_arguments): Initialize
+ has_crtbeginT_ to false.
+ (Input_arguments::has_crtbeginT): New function.
+ (Input_arguments::has_crtbeginT_): New bool member.
+ (Command_line::crtbeginT): New function.
+
2014-12-22 Cary Coutant <ccoutant@google.com>
* powerpc.cc (Target_powerpc::relocate): Fix overflow check.
diff --git a/gold/ehframe.cc b/gold/ehframe.cc
index c711bac..ce3741b 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 optimize_ehframe)
{
// Get the section contents.
section_size_type contents_len;
@@ -595,15 +596,21 @@ 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 it can't
+ // be optimized, then return false to force it to be handled as an
+ // ordinary input section.
+ if (!recognized_eh_frame_section
+ || (this->eh_frame_hdr_ == NULL && !optimize_ehframe))
{
- 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 +1231,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 optimize_ehframe);
#endif
#ifdef HAVE_TARGET_32_BIG
@@ -1238,7 +1246,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 optimize_ehframe);
#endif
#ifdef HAVE_TARGET_64_LITTLE
@@ -1252,7 +1261,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 optimize_ehframe);
#endif
#ifdef HAVE_TARGET_64_BIG
@@ -1266,7 +1276,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 optimize_ehframe);
#endif
} // End namespace gold.
diff --git a/gold/ehframe.h b/gold/ehframe.h
index 2ae12e0..93f7268 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. OPTIMIZE_EHFRAME is true if the exception frame section
+ // can be optimized.
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 optimize_ehframe);
// 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..a723d03 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -418,7 +418,8 @@ Layout_task_runner::run(Workqueue* workqueue, const Task* task)
// Layout methods.
-Layout::Layout(int number_of_input_files, Script_options* script_options)
+Layout::Layout(int number_of_input_files, Script_options* script_options,
+ bool has_crtbeginT)
: number_of_input_files_(number_of_input_files),
script_options_(script_options),
namepool_(),
@@ -469,6 +470,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),
+ optimize_ehframe_(!has_crtbeginT),
script_output_section_data_list_(),
segment_states_(NULL),
relaxation_debug_check_(NULL),
@@ -1428,7 +1430,8 @@ Layout::layout_eh_frame(Sized_relobj_file<size, big_endian>* object,
symbol_names_size,
shndx,
reloc_shndx,
- reloc_type))
+ reloc_type,
+ this->optimize_ehframe_))
{
os->update_flags_for_input_section(shdr.get_sh_flags());
@@ -1485,6 +1488,14 @@ Layout::make_eh_frame_section(const Relobj* object)
if (os == NULL)
return NULL;
+ // optimize_ehframe_ is false only if there is a crtbeginT file on
+ // command line. We can't optimize the exception frame section
+ // until we have seen the crtbeginT file.
+ if (!this->optimize_ehframe_
+ && object != NULL
+ && Layout::match_file_name(object, "crtbeginT"))
+ this->optimize_ehframe_ = true;
+
if (this->eh_frame_section_ == NULL)
{
this->eh_frame_section_ = os;
@@ -5092,19 +5103,18 @@ Layout::output_section_name(const Relobj* relobj, const char* name,
return name;
}
-// Return true if RELOBJ is an input file whose base name matches
-// FILE_NAME. The base name must have an extension of ".o", and must
-// be exactly FILE_NAME.o or FILE_NAME, one character, ".o". This is
+// Return true if FILE is an input file whose base name matches
+// MATCH. The base name must have an extension of ".o", and must
+// be exactly MATCH.o or MATCH, one character, ".o". This is
// to match crtbegin.o as well as crtbeginS.o without getting confused
// by other possibilities. Overall matching the file name this way is
// a dreadful hack, but the GNU linker does it in order to better
// support gcc, and we need to be compatible.
bool
-Layout::match_file_name(const Relobj* relobj, const char* match)
+Layout::match_file_name(const char* file, const char* match)
{
- const std::string& file_name(relobj->name());
- const char* base_name = lbasename(file_name.c_str());
+ const char* base_name = lbasename(file);
size_t match_len = strlen(match);
if (strncmp(base_name, match, match_len) != 0)
return false;
@@ -5114,6 +5124,17 @@ Layout::match_file_name(const Relobj* relobj, const char* match)
return memcmp(base_name + base_len - 2, ".o", 2) == 0;
}
+// Return true if FILE is an input file whose base name matches
+// MATCH. The base name must have an extension of ".o", and must
+// be exactly MATCH.o or MATCH, one character, ".o".
+
+bool
+Layout::match_file_name(const Relobj* relobj, const char* match)
+{
+ const std::string& file_name(relobj->name());
+ return Layout::match_file_name(file_name.c_str(), match);
+}
+
// Check if a comdat group or .gnu.linkonce section with the given
// NAME is selected for the link. If there is already a section,
// *KEPT_SECTION is set to point to the existing section and the
diff --git a/gold/layout.h b/gold/layout.h
index 032f5f3..31724a2 100644
--- a/gold/layout.h
+++ b/gold/layout.h
@@ -488,7 +488,7 @@ enum Output_section_order
class Layout
{
public:
- Layout(int number_of_input_files, Script_options*);
+ Layout(int number_of_input_files, Script_options*, bool has_crtbeginT);
~Layout()
{
@@ -757,6 +757,12 @@ class Layout
|| strncmp(name, ".stab", sizeof(".stab") - 1) == 0);
}
+ // Return true if FILE is an input file whose base name matches
+ // FILE_NAME. The base name must have an extension of ".o", and
+ // must be exactly FILE_NAME.o or FILE_NAME, one character, ".o".
+ static bool
+ match_file_name(const char* file, const char* file_name);
+
// Return true if RELOBJ is an input file whose base name matches
// FILE_NAME. The base name must have an extension of ".o", and
// must be exactly FILE_NAME.o or FILE_NAME, one character, ".o".
@@ -1420,6 +1426,8 @@ class Layout
Incremental_inputs* incremental_inputs_;
// Whether we record output section data created in script
bool record_output_section_data_from_script_;
+ // Whether to optimize the exception frame section.
+ bool optimize_ehframe_;
// 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.
diff --git a/gold/main.cc b/gold/main.cc
index bb86613..bbeff65 100644
--- a/gold/main.cc
+++ b/gold/main.cc
@@ -227,7 +227,8 @@ main(int argc, char** argv)
// The layout object.
Layout layout(command_line.number_of_input_files(),
- &command_line.script_options());
+ &command_line.script_options(),
+ command_line.crtbeginT());
if (layout.incremental_inputs() != NULL)
layout.incremental_inputs()->report_command_line(argc, argv);
diff --git a/gold/options.cc b/gold/options.cc
index 731061d..cf7af2d 100644
--- a/gold/options.cc
+++ b/gold/options.cc
@@ -38,6 +38,7 @@
#include "script.h"
#include "target-select.h"
#include "options.h"
+#include "layout.h"
#include "plugin.h"
namespace gold
@@ -1346,6 +1347,9 @@ Input_arguments::add_file(Input_file_argument& file)
return this->input_argument_list_.back().lib()->add_file(file);
}
this->input_argument_list_.push_back(Input_argument(file));
+ if (!this->has_crtbeginT_
+ && Layout::match_file_name(file.name(), "crtbeginT"))
+ this->has_crtbeginT_ = true;
return this->input_argument_list_.back();
}
diff --git a/gold/options.h b/gold/options.h
index 6d827f1..7e881df 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -1970,7 +1970,8 @@ class Input_arguments
typedef Input_argument_list::const_iterator const_iterator;
Input_arguments()
- : input_argument_list_(), in_group_(false), in_lib_(false), file_count_(0)
+ : input_argument_list_(), in_group_(false), in_lib_(false),
+ file_count_(0), has_crtbeginT_(false)
{ }
// Add a file.
@@ -2030,11 +2031,18 @@ class Input_arguments
number_of_input_files() const
{ return this->file_count_; }
+ // Return whether there is a crtbeginT file.
+ bool
+ has_crtbeginT() const
+ { return this->has_crtbeginT_; }
+
private:
Input_argument_list input_argument_list_;
bool in_group_;
bool in_lib_;
unsigned int file_count_;
+ // Whether there is a crtbeginT file.
+ bool has_crtbeginT_;
};
@@ -2103,6 +2111,11 @@ class Command_line
end() const
{ return this->inputs_.end(); }
+ // Whether there is a crtbeginT file.
+ bool
+ crtbeginT() const
+ { return this->inputs_.has_crtbeginT(); }
+
private:
Command_line(const Command_line&);
Command_line& operator=(const Command_line&);
--
1.9.3