diff --git a/binutils-2.23.51.0.1-gold-keep.patch b/binutils-2.23.51.0.1-gold-keep.patch new file mode 100644 index 0000000..e8570a0 --- /dev/null +++ b/binutils-2.23.51.0.1-gold-keep.patch @@ -0,0 +1,293 @@ +diff -rcp ../binutils-2.22.52.0.4.orig/gold/layout.cc gold/layout.cc +*** ../binutils-2.22.52.0.4.orig/gold/layout.cc 2012-08-14 09:38:36.359409453 +0100 +--- gold/layout.cc 2012-08-14 09:39:16.393410563 +0100 +*************** Layout::get_output_section(const char* n +*** 749,754 **** +--- 749,774 ---- + } + } + ++ // Returns TRUE iff NAME (an input section from RELOBJ) will ++ // be mapped to an output section that should be KEPT. ++ ++ bool ++ Layout::keep_input_section(const Relobj* relobj, const char* name) ++ { ++ if (! this->script_options_->saw_sections_clause()) ++ return false; ++ ++ Script_sections* ss = this->script_options_->script_sections(); ++ const char* file_name = relobj == NULL ? NULL : relobj->name().c_str(); ++ Output_section** output_section_slot; ++ Script_sections::Section_type script_section_type; ++ bool keep; ++ ++ name = ss->output_section_name(file_name, name, &output_section_slot, ++ &script_section_type, &keep); ++ return name != NULL && keep; ++ } ++ + // Pick the output section to use for section NAME, in input file + // RELOBJ, with type TYPE and flags FLAGS. RELOBJ may be NULL for a + // linker created section. IS_INPUT_SECTION is true if we are +*************** Layout::choose_output_section(const Relo +*** 789,796 **** + Output_section** output_section_slot; + Script_sections::Section_type script_section_type; + const char* orig_name = name; + name = ss->output_section_name(file_name, name, &output_section_slot, +! &script_section_type); + if (name == NULL) + { + gold_debug(DEBUG_SCRIPT, _("Unable to create output section '%s' " +--- 809,818 ---- + Output_section** output_section_slot; + Script_sections::Section_type script_section_type; + const char* orig_name = name; ++ bool keep; + name = ss->output_section_name(file_name, name, &output_section_slot, +! &script_section_type, &keep); +! + if (name == NULL) + { + gold_debug(DEBUG_SCRIPT, _("Unable to create output section '%s' " +diff -rcp ../binutils-2.22.52.0.4.orig/gold/layout.h gold/layout.h +*** ../binutils-2.22.52.0.4.orig/gold/layout.h 2012-08-14 09:38:52.579409903 +0100 +--- gold/layout.h 2012-08-14 09:39:16.403410563 +0100 +*************** class Layout +*** 920,925 **** +--- 920,930 ---- + section_list() const + { return this->section_list_; } + ++ // Returns TRUE iff NAME (an input section from RELOBJ) will ++ // be mapped to an output section that should be KEPT. ++ bool ++ keep_input_section(const Relobj*, const char*); ++ + private: + Layout(const Layout&); + Layout& operator=(const Layout&); +diff -rcp ../binutils-2.22.52.0.4.orig/gold/object.cc gold/object.cc +*** ../binutils-2.22.52.0.4.orig/gold/object.cc 2012-08-14 09:38:43.151409641 +0100 +--- gold/object.cc 2012-08-14 09:39:16.412410563 +0100 +*************** Sized_relobj_file::do_ +*** 1437,1442 **** +--- 1437,1443 ---- + if (is_gc_pass_one && parameters->options().gc_sections()) + { + if (this->is_section_name_included(name) ++ || layout->keep_input_section (this, name) + || shdr.get_sh_type() == elfcpp::SHT_INIT_ARRAY + || shdr.get_sh_type() == elfcpp::SHT_FINI_ARRAY) + { +diff -rcp ../binutils-2.22.52.0.4.orig/gold/script-sections.cc gold/script-sections.cc +*** ../binutils-2.22.52.0.4.orig/gold/script-sections.cc 2012-08-14 09:38:49.437409815 +0100 +--- gold/script-sections.cc 2012-08-14 09:39:16.413410563 +0100 +*************** class Sections_element +*** 582,588 **** + // Output_section_definition. + virtual const char* + output_section_name(const char*, const char*, Output_section***, +! Script_sections::Section_type*) + { return NULL; } + + // Initialize OSP with an output section. +--- 582,588 ---- + // Output_section_definition. + virtual const char* + output_section_name(const char*, const char*, Output_section***, +! Script_sections::Section_type*, bool*) + { return NULL; } + + // Initialize OSP with an output section. +*************** class Output_section_element +*** 800,806 **** + // Return whether this element matches FILE_NAME and SECTION_NAME. + // The only real implementation is in Output_section_element_input. + virtual bool +! match_name(const char*, const char*) const + { return false; } + + // Set section addresses. This includes applying assignments if the +--- 800,806 ---- + // Return whether this element matches FILE_NAME and SECTION_NAME. + // The only real implementation is in Output_section_element_input. + virtual bool +! match_name(const char*, const char*, bool *) const + { return false; } + + // Set section addresses. This includes applying assignments if the +*************** class Output_section_element_input : pub +*** 1238,1247 **** + *dot_section = this->final_dot_section_; + } + +! // See whether we match FILE_NAME and SECTION_NAME as an input +! // section. + bool +! match_name(const char* file_name, const char* section_name) const; + + // Set the section address. + void +--- 1238,1247 ---- + *dot_section = this->final_dot_section_; + } + +! // See whether we match FILE_NAME and SECTION_NAME as an input section. +! // If we do then also indicate whether the section should be KEPT. + bool +! match_name(const char* file_name, const char* section_name, bool* keep) const; + + // Set the section address. + void +*************** Output_section_element_input::match_file +*** 1393,1407 **** + return true; + } + +! // See whether we match FILE_NAME and SECTION_NAME. + + bool + Output_section_element_input::match_name(const char* file_name, +! const char* section_name) const + { + if (!this->match_file_name(file_name)) + return false; + + // If there are no section name patterns, then we match. + if (this->input_section_patterns_.empty()) + return true; +--- 1393,1411 ---- + return true; + } + +! // See whether we match FILE_NAME and SECTION_NAME. If we do then +! // KEEP indicates whether the section should survive garbage collection. + + bool + Output_section_element_input::match_name(const char* file_name, +! const char* section_name, +! bool *keep) const + { + if (!this->match_file_name(file_name)) + return false; + ++ *keep = this->keep_; ++ + // If there are no section name patterns, then we match. + if (this->input_section_patterns_.empty()) + return true; +*************** class Output_section_definition : public +*** 1861,1867 **** + // section name. + const char* + output_section_name(const char* file_name, const char* section_name, +! Output_section***, Script_sections::Section_type*); + + // Initialize OSP with an output section. + void +--- 1865,1872 ---- + // section name. + const char* + output_section_name(const char* file_name, const char* section_name, +! Output_section***, Script_sections::Section_type*, +! bool*); + + // Initialize OSP with an output section. + void +*************** Output_section_definition::output_sectio +*** 2146,2159 **** + const char* file_name, + const char* section_name, + Output_section*** slot, +! Script_sections::Section_type* psection_type) + { + // Ask each element whether it matches NAME. + for (Output_section_elements::const_iterator p = this->elements_.begin(); + p != this->elements_.end(); + ++p) + { +! if ((*p)->match_name(file_name, section_name)) + { + // We found a match for NAME, which means that it should go + // into this output section. +--- 2151,2165 ---- + const char* file_name, + const char* section_name, + Output_section*** slot, +! Script_sections::Section_type* psection_type, +! bool* keep) + { + // Ask each element whether it matches NAME. + for (Output_section_elements::const_iterator p = this->elements_.begin(); + p != this->elements_.end(); + ++p) + { +! if ((*p)->match_name(file_name, section_name, keep)) + { + // We found a match for NAME, which means that it should go + // into this output section. +*************** Script_sections::output_section_name( +*** 3365,3371 **** + const char* file_name, + const char* section_name, + Output_section*** output_section_slot, +! Script_sections::Section_type* psection_type) + { + for (Sections_elements::const_iterator p = this->sections_elements_->begin(); + p != this->sections_elements_->end(); +--- 3371,3378 ---- + const char* file_name, + const char* section_name, + Output_section*** output_section_slot, +! Script_sections::Section_type* psection_type, +! bool* keep) + { + for (Sections_elements::const_iterator p = this->sections_elements_->begin(); + p != this->sections_elements_->end(); +*************** Script_sections::output_section_name( +*** 3373,3379 **** + { + const char* ret = (*p)->output_section_name(file_name, section_name, + output_section_slot, +! psection_type); + + if (ret != NULL) + { +--- 3380,3386 ---- + { + const char* ret = (*p)->output_section_name(file_name, section_name, + output_section_slot, +! psection_type, keep); + + if (ret != NULL) + { +diff -rcp ../binutils-2.22.52.0.4.orig/gold/script-sections.h gold/script-sections.h +*** ../binutils-2.22.52.0.4.orig/gold/script-sections.h 2012-08-14 09:38:41.679409601 +0100 +--- gold/script-sections.h 2012-08-14 09:39:16.421410563 +0100 +*************** class Script_sections +*** 163,172 **** + // PSCRIPT_SECTION_TYPE points to a location for returning the section + // type specified in script. This can be SCRIPT_SECTION_TYPE_NONE if + // no type is specified. + const char* + output_section_name(const char* file_name, const char* section_name, + Output_section*** output_section_slot, +! Section_type* pscript_section_type); + + // Place a marker for an orphan output section into the SECTIONS + // clause. +--- 163,174 ---- + // PSCRIPT_SECTION_TYPE points to a location for returning the section + // type specified in script. This can be SCRIPT_SECTION_TYPE_NONE if + // no type is specified. ++ // *KEEP indicates whether the section should survive garbage collection. + const char* + output_section_name(const char* file_name, const char* section_name, + Output_section*** output_section_slot, +! Section_type* pscript_section_type, +! bool* keep); + + // Place a marker for an orphan output section into the SECTIONS + // clause. diff --git a/binutils.spec b/binutils.spec index 1d49245..cc29bf4 100644 --- a/binutils.spec +++ b/binutils.spec @@ -17,7 +17,7 @@ Summary: A GNU collection of binary utilities Name: %{?cross}binutils%{?_with_debug:-debug} Version: 2.23.51.0.1 -Release: 1%{?dist} +Release: 2%{?dist} License: GPLv3+ Group: Development/Tools URL: http://sources.redhat.com/binutils @@ -40,6 +40,8 @@ Patch08: binutils-2.22.52.0.1-relro-on-by-default.patch Patch09: binutils-2.22.52.0.1-export-demangle.h.patch # Disable checks that config.h has been included before system headers. BZ #845084 Patch10: binutils-2.22.52.0.4-no-config-h-check.patch +# Make GOLD honour the KEEP directive in linker scripts. +Patch11: binutils-2.23.51.0.1-gold-keep.patch %define gold_arches %ix86 x86_64 @@ -143,6 +145,7 @@ using libelf instead of BFD. %endif %patch09 -p0 -b .export-demangle-h~ %patch10 -p0 -b .no-config-h-check~ +%patch11 -p0 -b .gold-keep~ # We cannot run autotools as there is an exact requirement of autoconf-2.59. @@ -437,6 +440,9 @@ exit 0 %endif # %{isnative} %changelog +* Tue Aug 14 2012 Nick Clifton - 2.23.51.0.1-2 +- Make GOLD honour KEEP directives in linker scripts (#8333355) + * Wed Aug 08 2012 Nick Clifton - 2.23.51.0.1-1 - Rebase on 2.23.51.0.1 release. (#846433) - Retire binutils-2.22.52.0.4-dwz.patch, binutils-2.22.52.0.4-ar-4Gb.patch, binutils-2.22.52.0.4-arm-plt-refcount.patch, binutils-2.22.52.0.4-s390-64bit-archive.patch.