summaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
authorSriraman Tallam <tmsriram@google.com>2012-12-19 02:55:15 +0000
committerSriraman Tallam <tmsriram@google.com>2012-12-19 02:55:15 +0000
commit52d9b4b2c19a0c421a291b24529462d7bc8cac8e (patch)
tree050e11e7c954cf6bf52c37bcc870750cac14a8cc /gold
parent20f95cf8afd097e7320237e68333ce5f65c851dc (diff)
downloadbinutils-redhat-52d9b4b2c19a0c421a291b24529462d7bc8cac8e.tar.gz
Group text sections with prefixes .text.unlikely,.text.hot and .text.startup
by default. 2012-12-18 Sriraman Tallam <tmsriram@google.com> * layout.cc (Layout::is_section_name_prefix_grouped): New function. * layout.h (Layout::is_section_name_prefix_grouped): New function. * output.cc (Output_section::add_input_section): Check if section name contains special prefix. Keep input sections to sort such sections. (Output_section::Input_section_sort_section_order_index_compare ::operator()): Group sections according to prefixes. * (Output_section::sort_attached_input_sections): Add condition to Input_section_entry constructor call. * testsuite/Makefile.am (text_section_grouping): New test. * testsuite/Makefile.in: Regenerate. * testsuite/text_section_grouping.cc: New file. * testsuite/text_section_grouping.sh: New file.
Diffstat (limited to 'gold')
-rw-r--r--gold/ChangeLog16
-rw-r--r--gold/layout.cc14
-rw-r--r--gold/layout.h5
-rw-r--r--gold/output.cc79
-rw-r--r--gold/testsuite/Makefile.am10
-rw-r--r--gold/testsuite/Makefile.in11
-rw-r--r--gold/testsuite/text_section_grouping.cc72
-rwxr-xr-xgold/testsuite/text_section_grouping.sh65
8 files changed, 265 insertions, 7 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index b97d8a2ead..62ddbc688a 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,19 @@
+2012-12-18 Sriraman Tallam <tmsriram@google.com>
+
+ * layout.cc (Layout::is_section_name_prefix_grouped): New function.
+ * layout.h (Layout::is_section_name_prefix_grouped): New function.
+ * output.cc (Output_section::add_input_section): Check if section
+ name contains special prefix. Keep input sections to sort such
+ sections.
+ (Output_section::Input_section_sort_section_order_index_compare
+ ::operator()): Group sections according to prefixes.
+ * (Output_section::sort_attached_input_sections): Add condition
+ to Input_section_entry constructor call.
+ * testsuite/Makefile.am (text_section_grouping): New test.
+ * testsuite/Makefile.in: Regenerate.
+ * testsuite/text_section_grouping.cc: New file.
+ * testsuite/text_section_grouping.sh: New file.
+
2012-12-17 Nick Clifton <nickc@redhat.com>
* Makefile.am: Add copyright notice.
diff --git a/gold/layout.cc b/gold/layout.cc
index 60fabb8b81..62b4cadf9d 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -2409,6 +2409,20 @@ Layout::relaxation_loop_body(
return off;
}
+// By default, gold groups input sections with certain prefixes. This
+// function returns true if this section name NAME contains such a prefix.
+
+bool
+Layout::is_section_name_prefix_grouped(const char *name)
+{
+ if (is_prefix_of(".text.unlikely", name)
+ || is_prefix_of(".text.startup", name)
+ || is_prefix_of(".text.hot", name))
+ return true;
+
+ return false;
+}
+
// Search the list of patterns and find the postion of the given section
// name in the output section. If the section name matches a glob
// pattern and a non-glob name, then the non-glob position takes
diff --git a/gold/layout.h b/gold/layout.h
index cf41f323e7..71f1aa7a49 100644
--- a/gold/layout.h
+++ b/gold/layout.h
@@ -552,6 +552,11 @@ class Layout
// Maps section SECN to SEGMENT s.
void
insert_section_segment_map(Const_section_id secn, Unique_segment_info *s);
+
+ // By default, gold groups input sections with certain prefixes. This
+ // function returns true if this section name NAME contains such a prefix.
+ bool
+ is_section_name_prefix_grouped(const char *name);
bool
is_section_ordering_specified()
diff --git a/gold/output.cc b/gold/output.cc
index 9e3b0b4de9..39eb1b7dc7 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -2478,6 +2478,19 @@ Output_section::add_input_section(Layout* layout,
}
}
+ // The GNU linker groups input sections whose names match .text.unlikely.*.
+ // This is used to get better code layout. We are compatible.
+ // Additionally, it could also be beneficial to group .text.hot.*,
+ // .text.startup.* prefixed input sections. Function
+ // "is_section_name_prefix_grouped" in layout.cc determines the input
+ // section prefixes that must be grouped.
+ if (!have_sections_script
+ && !parameters->options().relocatable()
+ && !this->input_section_order_specified()
+ && !this->must_sort_attached_input_sections()
+ && layout->is_section_name_prefix_grouped(secname))
+ this->set_input_section_order_specified();
+
// We need to keep track of this section if we are already keeping
// track of sections, or if we are relaxing. Also, if this is a
// section which requires sorting, or which may require sorting in
@@ -2491,7 +2504,8 @@ Output_section::add_input_section(Layout* layout,
|| this->must_sort_attached_input_sections()
|| parameters->options().user_set_Map()
|| parameters->target().may_relax()
- || layout->is_section_ordering_specified())
+ || layout->is_section_ordering_specified()
+ || this->input_section_order_specified())
{
Input_section isecn(object, shndx, input_section_size, addralign);
/* If section ordering is requested by specifying a ordering file,
@@ -3484,7 +3498,9 @@ Output_section::Input_section_sort_init_fini_compare::operator()(
// Return true if S1 should come before S2. Sections that do not match
// any pattern in the section ordering file are placed ahead of the sections
-// that match some pattern.
+// that match some pattern. This function is also used to group text according
+// to their prefix. The following prefixes are recognized: ".text.startup",
+// ".text.hot", and ".text.unlikely".
bool
Output_section::Input_section_sort_section_order_index_compare::operator()(
@@ -3494,11 +3510,59 @@ Output_section::Input_section_sort_section_order_index_compare::operator()(
unsigned int s1_secn_index = s1.input_section().section_order_index();
unsigned int s2_secn_index = s2.input_section().section_order_index();
- // Keep input order if section ordering cannot determine order.
- if (s1_secn_index == s2_secn_index)
- return s1.index() < s2.index();
+ // If section ordering is specified, it takes precedence.
+ if (s1_secn_index != s2_secn_index)
+ return s1_secn_index < s2_secn_index;
+
+ // 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();
+ }
+
+ // If it is a text section use the following order:
+ // .text.unlikely, .text.startup, .text.hot. The prefixes
+ // must match those in function is_section_name_prefix_grouped
+ // in layout.cc
+ const char* section_prefix [] =
+ {
+ ".text.unlikely",
+ ".text.startup",
+ ".text.hot"
+ };
+
+ const unsigned int num_prefixes
+ = sizeof(section_prefix) / sizeof(const char*);
+
+ unsigned int s1_group_index = num_prefixes;
+ unsigned int s2_group_index = num_prefixes;
+
+ unsigned int flag_done = 0;
+ for (unsigned int i = 0; i < num_prefixes && flag_done < 2; i++)
+ {
+ if (s1_group_index == num_prefixes
+ && is_prefix_of(section_prefix[i], s1.section_name().c_str()))
+ {
+ s1_group_index = i;
+ flag_done++;
+ }
- return s1_secn_index < s2_secn_index;
+ if (s2_group_index == num_prefixes
+ && is_prefix_of(section_prefix[i], s2.section_name().c_str()))
+ {
+ s2_group_index = i;
+ flag_done++;
+ }
+ }
+
+ if (s1_group_index == s2_group_index)
+ return s1.index() < s2.index();
+ else
+ return s1_group_index < s2_group_index;
}
// This updates the section order index of input sections according to the
@@ -3559,7 +3623,8 @@ Output_section::sort_attached_input_sections()
p != this->input_sections_.end();
++p, ++i)
sort_list.push_back(Input_section_sort_entry(*p, i,
- this->must_sort_attached_input_sections()));
+ (this->must_sort_attached_input_sections()
+ || this->input_section_order_specified())));
// Sort the input sections.
if (this->must_sort_attached_input_sections())
diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
index c5c8a99b4c..745e13d091 100644
--- a/gold/testsuite/Makefile.am
+++ b/gold/testsuite/Makefile.am
@@ -250,6 +250,16 @@ final_layout: final_layout.o final_layout_sequence.txt gcctestdir/ld
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
+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_grouping.stdout: text_section_grouping
+ $(TEST_NM) -n --synthetic text_section_grouping > text_section_grouping.stdout
+
check_PROGRAMS += icf_virtual_function_folding_test
MOSTLYCLEANFILES += icf_virtual_function_folding_test
icf_virtual_function_folding_test.o: icf_virtual_function_folding_test.cc
diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in
index 6d9c630067..b1058b4d0b 100644
--- a/gold/testsuite/Makefile.in
+++ b/gold/testsuite/Makefile.in
@@ -81,6 +81,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_so_test.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ final_layout.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ text_section_grouping.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_string_merge_test.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_sht_rel_addend_test.sh \
@@ -111,6 +112,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_so_test_1.stdout \
@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@ 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 \
@@ -122,6 +124,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_test icf_keep_unique_test \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_safe_test icf_safe_so_test \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ final_layout \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ text_section_grouping \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ final_layout_sequence.txt \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_virtual_function_folding_test \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_preemptible_functions_test \
@@ -3701,6 +3704,8 @@ icf_safe_so_test.sh.log: icf_safe_so_test.sh
@p='icf_safe_so_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
final_layout.sh.log: final_layout.sh
@p='final_layout.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+text_section_grouping.sh.log: text_section_grouping.sh
+ @p='text_section_grouping.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
icf_preemptible_functions_test.sh.log: icf_preemptible_functions_test.sh
@p='icf_preemptible_functions_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
icf_string_merge_test.sh.log: icf_string_merge_test.sh
@@ -4348,6 +4353,12 @@ uninstall-am:
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,--section-ordering-file,final_layout_sequence.txt final_layout.o
@GCC_TRUE@@NATIVE_LINKER_TRUE@final_layout.stdout: final_layout
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) -n --synthetic final_layout > final_layout.stdout
+@GCC_TRUE@@NATIVE_LINKER_TRUE@text_section_grouping.o: text_section_grouping.cc
+@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_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@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
diff --git a/gold/testsuite/text_section_grouping.cc b/gold/testsuite/text_section_grouping.cc
new file mode 100644
index 0000000000..5a3a809f0c
--- /dev/null
+++ b/gold/testsuite/text_section_grouping.cc
@@ -0,0 +1,72 @@
+// text_section_grouping.cc -- a test case for gold
+
+// Copyright 2012 Free Software Foundation, Inc.
+// Written by Sriraman Tallam <tmsriram@google.com>.
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// The goal of this program is to verify if .text sections are grouped
+// according to prefix. .text.unlikely, .text.startup and .text.hot should
+// be grouped and placed together.
+
+extern "C"
+__attribute__ ((section(".text.hot.foo")))
+int hot_foo()
+{
+ return 1;
+}
+
+extern "C"
+__attribute__ ((section(".text.startup.foo")))
+int startup_foo()
+{
+ return 1;
+}
+
+extern "C"
+__attribute__ ((section(".text.unlikely.foo")))
+int unlikely_foo()
+{
+ return 1;
+}
+
+extern "C"
+__attribute__ ((section(".text.hot.bar")))
+int hot_bar()
+{
+ return 1;
+}
+
+extern "C"
+__attribute__ ((section(".text.startup.bar")))
+int startup_bar()
+{
+ return 1;
+}
+
+extern "C"
+__attribute__ ((section(".text.unlikely.bar")))
+int unlikely_bar()
+{
+ return 1;
+}
+
+int main()
+{
+ return 1;
+}
diff --git a/gold/testsuite/text_section_grouping.sh b/gold/testsuite/text_section_grouping.sh
new file mode 100755
index 0000000000..a79836ca0c
--- /dev/null
+++ b/gold/testsuite/text_section_grouping.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+
+# text_section_grouping.sh -- test
+
+# Copyright 2012 Free Software Foundation, Inc.
+# Written by Sriraman Tallam <tmsriram@google.com>.
+
+# This file is part of gold.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+# The goal of this program is to verify if .text sections are grouped
+# according to prefix. .text.unlikely, .text.startup and .text.hot should
+# be grouped and placed together.
+
+set -e
+
+check()
+{
+ awk "
+BEGIN { saw1 = 0; saw2 = 0; err = 0; }
+/.*$2\$/ { saw1 = 1; }
+/.*$3\$/ {
+ saw2 = 1;
+ if (!saw1)
+ {
+ printf \"layout of $2 and $3 is not right\\n\";
+ err = 1;
+ exit 1;
+ }
+ }
+END {
+ if (!saw1 && !err)
+ {
+ printf \"did not see $2\\n\";
+ exit 1;
+ }
+ if (!saw2 && !err)
+ {
+ printf \"did not see $3\\n\";
+ exit 1;
+ }
+ }" $1
+}
+
+# addr (unlikely_*) < addr (startup_*) < addr (hot_*)
+check text_section_grouping.stdout "unlikely_foo" "startup_foo"
+check text_section_grouping.stdout "startup_foo" "hot_foo"
+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"