Default text reordering fix with a flag to turn it off.
2013-01-24 Sriraman Tallam <tmsriram@google.com> * layout.cc (Layout::layout): Check for option text_reorder. (Layout::make_output_section): Ditto. * options.h (text_reorder): New option. * output.cc (Input_section_sort_compare): Remove special ordering of section names. (Output_section:: Input_section_sort_section_name_special_ordering_compare:: operator()): New function. (Output_section::sort_attached_input_sections): Use new sort function for .text. * output.h (Input_section_sort_section_name_special_ordering_compare): New struct. * testsuite/Makefile.am (text_section_grouping): Test option --no-text-reorder * testsuite/Makefile.in: Regenerate. * testsuite/text_section_grouping.sh: Check order of functions without default text reordering.
This commit is contained in:
parent
45e6c716a9
commit
c6ac678db5
8 changed files with 99 additions and 19 deletions
|
@ -1,3 +1,23 @@
|
|||
2013-01-24 Sriraman Tallam <tmsriram@google.com>
|
||||
|
||||
* layout.cc (Layout::layout): Check for option text_reorder.
|
||||
(Layout::make_output_section): Ditto.
|
||||
* options.h (text_reorder): New option.
|
||||
* output.cc (Input_section_sort_compare): Remove special ordering
|
||||
of section names.
|
||||
(Output_section::
|
||||
Input_section_sort_section_name_special_ordering_compare::
|
||||
operator()): New function.
|
||||
(Output_section::sort_attached_input_sections): Use new sort function
|
||||
for .text.
|
||||
* output.h (Input_section_sort_section_name_special_ordering_compare):
|
||||
New struct.
|
||||
* testsuite/Makefile.am (text_section_grouping): Test option
|
||||
--no-text-reorder
|
||||
* testsuite/Makefile.in: Regenerate.
|
||||
* testsuite/text_section_grouping.sh: Check order of functions without
|
||||
default text reordering.
|
||||
|
||||
2013-01-18 Mike Frysinger <vapier@gentoo.org>
|
||||
|
||||
* options.h (General_options): Change default to true for new_dtags.
|
||||
|
|
|
@ -1149,7 +1149,8 @@ Layout::layout(Sized_relobj_file<size, big_endian>* object, unsigned int shndx,
|
|||
|
||||
// By default the GNU linker sorts some special text sections ahead
|
||||
// of others. We are compatible.
|
||||
if (!this->script_options_->saw_sections_clause()
|
||||
if (parameters->options().text_reorder()
|
||||
&& !this->script_options_->saw_sections_clause()
|
||||
&& !this->is_section_ordering_specified()
|
||||
&& !parameters->options().relocatable()
|
||||
&& Layout::special_ordering_of_input_section(name) >= 0)
|
||||
|
@ -1646,7 +1647,8 @@ Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
|
|||
// sections before other .text sections. We are compatible. We
|
||||
// need to know that this might happen before we attach any input
|
||||
// sections.
|
||||
if (!this->script_options_->saw_sections_clause()
|
||||
if (parameters->options().text_reorder()
|
||||
&& !this->script_options_->saw_sections_clause()
|
||||
&& !this->is_section_ordering_specified()
|
||||
&& !parameters->options().relocatable()
|
||||
&& strcmp(name, ".text") == 0)
|
||||
|
|
|
@ -878,6 +878,11 @@ class General_options
|
|||
DEFINE_dirlist(library_path, options::TWO_DASHES, 'L',
|
||||
N_("Add directory to search path"), N_("DIR"));
|
||||
|
||||
DEFINE_bool(text_reorder, options::TWO_DASHES, '\0', true,
|
||||
N_("Enable text section reordering for GCC section names "
|
||||
"(default)"),
|
||||
N_("Disable text section reordering for GCC section names"));
|
||||
|
||||
DEFINE_bool(nostdlib, options::ONE_DASH, '\0', false,
|
||||
N_(" Only search directories specified on the command line."),
|
||||
NULL);
|
||||
|
|
|
@ -3389,19 +3389,6 @@ Output_section::Input_section_sort_compare::operator()(
|
|||
return s1.index() < s2.index();
|
||||
}
|
||||
|
||||
// Some input section names have special ordering requirements.
|
||||
int o1 = Layout::special_ordering_of_input_section(s1.section_name().c_str());
|
||||
int o2 = Layout::special_ordering_of_input_section(s2.section_name().c_str());
|
||||
if (o1 != o2)
|
||||
{
|
||||
if (o1 < 0)
|
||||
return false;
|
||||
else if (o2 < 0)
|
||||
return true;
|
||||
else
|
||||
return o1 < o2;
|
||||
}
|
||||
|
||||
// A section with a priority follows a section without a priority.
|
||||
bool s1_has_priority = s1.has_priority();
|
||||
bool s2_has_priority = s2.has_priority();
|
||||
|
@ -3508,6 +3495,42 @@ Output_section::Input_section_sort_section_order_index_compare::operator()(
|
|||
return s1_secn_index < s2_secn_index;
|
||||
}
|
||||
|
||||
// Return true if S1 should come before S2. This is the sort comparison
|
||||
// function for .text to sort sections with prefixes
|
||||
// .text.{unlikely,exit,startup,hot} before other sections.
|
||||
bool
|
||||
Output_section::Input_section_sort_section_name_special_ordering_compare
|
||||
::operator()(
|
||||
const Output_section::Input_section_sort_entry& s1,
|
||||
const Output_section::Input_section_sort_entry& s2) const
|
||||
{
|
||||
// We sort all the sections with no names to the end.
|
||||
if (!s1.section_has_name() || !s2.section_has_name())
|
||||
{
|
||||
if (s1.section_has_name())
|
||||
return true;
|
||||
if (s2.section_has_name())
|
||||
return false;
|
||||
return s1.index() < s2.index();
|
||||
}
|
||||
|
||||
// Some input section names have special ordering requirements.
|
||||
int o1 = Layout::special_ordering_of_input_section(s1.section_name().c_str());
|
||||
int o2 = Layout::special_ordering_of_input_section(s2.section_name().c_str());
|
||||
if (o1 != o2)
|
||||
{
|
||||
if (o1 < 0)
|
||||
return false;
|
||||
else if (o2 < 0)
|
||||
return true;
|
||||
else
|
||||
return o1 < o2;
|
||||
}
|
||||
|
||||
// Keep input order otherwise.
|
||||
return s1.index() < s2.index();
|
||||
}
|
||||
|
||||
// This updates the section order index of input sections according to the
|
||||
// the order specified in the mapping from Section id to order index.
|
||||
|
||||
|
@ -3576,6 +3599,9 @@ Output_section::sort_attached_input_sections()
|
|||
|| this->type() == elfcpp::SHT_FINI_ARRAY)
|
||||
std::sort(sort_list.begin(), sort_list.end(),
|
||||
Input_section_sort_init_fini_compare());
|
||||
else if (strcmp(this->name(), ".text") == 0)
|
||||
std::sort(sort_list.begin(), sort_list.end(),
|
||||
Input_section_sort_section_name_special_ordering_compare());
|
||||
else
|
||||
std::sort(sort_list.begin(), sort_list.end(),
|
||||
Input_section_sort_compare());
|
||||
|
|
|
@ -4200,6 +4200,15 @@ class Output_section : public Output_data
|
|||
const Input_section_sort_entry&) const;
|
||||
};
|
||||
|
||||
// This is the sort comparison function for .text to sort sections with
|
||||
// prefixes .text.{unlikely,exit,startup,hot} before other sections.
|
||||
struct Input_section_sort_section_name_special_ordering_compare
|
||||
{
|
||||
bool
|
||||
operator()(const Input_section_sort_entry&,
|
||||
const Input_section_sort_entry&) const;
|
||||
};
|
||||
|
||||
// Fill data. This is used to fill in data between input sections.
|
||||
// It is also used for data statements (BYTE, WORD, etc.) in linker
|
||||
// scripts. When we have to keep track of the input sections, we
|
||||
|
|
|
@ -259,14 +259,18 @@ final_layout.stdout: final_layout
|
|||
$(TEST_NM) -n --synthetic final_layout > final_layout.stdout
|
||||
|
||||
check_SCRIPTS += text_section_grouping.sh
|
||||
check_DATA += text_section_grouping.stdout
|
||||
MOSTLYCLEANFILES += text_section_grouping
|
||||
check_DATA += text_section_grouping.stdout text_section_no_grouping.stdout
|
||||
MOSTLYCLEANFILES += text_section_grouping text_section_no_grouping
|
||||
text_section_grouping.o: text_section_grouping.cc
|
||||
$(CXXCOMPILE) -O0 -c -ffunction-sections -g -o $@ $<
|
||||
text_section_grouping: text_section_grouping.o gcctestdir/ld
|
||||
$(CXXLINK) -Bgcctestdir/ text_section_grouping.o
|
||||
text_section_no_grouping: text_section_grouping.o gcctestdir/ld
|
||||
$(CXXLINK) -Bgcctestdir/ -Wl,--no-text-reorder text_section_grouping.o
|
||||
text_section_grouping.stdout: text_section_grouping
|
||||
$(TEST_NM) -n --synthetic text_section_grouping > text_section_grouping.stdout
|
||||
$(TEST_NM) -n --synthetic text_section_grouping > text_section_grouping.stdout
|
||||
text_section_no_grouping.stdout: text_section_no_grouping
|
||||
$(TEST_NM) -n --synthetic text_section_no_grouping > text_section_no_grouping.stdout
|
||||
|
||||
check_PROGRAMS += icf_virtual_function_folding_test
|
||||
MOSTLYCLEANFILES += icf_virtual_function_folding_test icf_virtual_function_folding_test.map
|
||||
|
|
|
@ -113,6 +113,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
|
|||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_so_test_2.stdout \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ final_layout.stdout \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ text_section_grouping.stdout \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ text_section_no_grouping.stdout \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test.stdout \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_string_merge_test.stdout \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_sht_rel_addend_test.stdout \
|
||||
|
@ -128,6 +129,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
|
|||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ final_layout_sequence.txt \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ final_layout_script.lds \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ text_section_grouping \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ text_section_no_grouping \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_virtual_function_folding_test \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_virtual_function_folding_test.map \
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test \
|
||||
|
@ -4376,8 +4378,12 @@ uninstall-am:
|
|||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -ffunction-sections -g -o $@ $<
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@text_section_grouping: text_section_grouping.o gcctestdir/ld
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ text_section_grouping.o
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@text_section_no_grouping: text_section_grouping.o gcctestdir/ld
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,--no-text-reorder text_section_grouping.o
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@text_section_grouping.stdout: text_section_grouping
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) -n --synthetic text_section_grouping > text_section_grouping.stdout
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) -n --synthetic text_section_grouping > text_section_grouping.stdout
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@text_section_no_grouping.stdout: text_section_no_grouping
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) -n --synthetic text_section_no_grouping > text_section_no_grouping.stdout
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_virtual_function_folding_test.o: icf_virtual_function_folding_test.cc
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -ffunction-sections -fPIE -g -o $@ $<
|
||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_virtual_function_folding_test: icf_virtual_function_folding_test.o gcctestdir/ld
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
# according to prefix. .text.unlikely, .text.startup and .text.hot should
|
||||
# be grouped and placed together.
|
||||
|
||||
# Also check if the functions do not get grouped with option --no-text-reorder.
|
||||
|
||||
set -e
|
||||
|
||||
check()
|
||||
|
@ -63,3 +65,9 @@ check text_section_grouping.stdout "unlikely_bar" "startup_bar"
|
|||
check text_section_grouping.stdout "startup_bar" "hot_bar"
|
||||
check text_section_grouping.stdout "unlikely_foo" "startup_bar"
|
||||
check text_section_grouping.stdout "startup_foo" "hot_bar"
|
||||
|
||||
check text_section_no_grouping.stdout "hot_foo" "startup_foo"
|
||||
check text_section_no_grouping.stdout "startup_foo" "unlikely_foo"
|
||||
check text_section_no_grouping.stdout "unlikely_foo" "hot_bar"
|
||||
check text_section_no_grouping.stdout "hot_bar" "startup_bar"
|
||||
check text_section_no_grouping.stdout "startup_bar" "unlikely_bar"
|
||||
|
|
Loading…
Reference in a new issue