Default text reordering fix with a flag to turn it off.
authorSriraman Tallam <tmsriram@google.com>
Thu, 24 Jan 2013 18:49:55 +0000 (18:49 +0000)
committerSriraman Tallam <tmsriram@google.com>
Thu, 24 Jan 2013 18:49:55 +0000 (18:49 +0000)
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.

gold/ChangeLog
gold/layout.cc
gold/options.h
gold/output.cc
gold/output.h
gold/testsuite/Makefile.am
gold/testsuite/Makefile.in
gold/testsuite/text_section_grouping.sh

index 8e70fdd..bcf8c06 100644 (file)
@@ -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.
index 250782a..1eb2cc0 100644 (file)
@@ -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)
index 9e65e8d..c138fa2 100644 (file)
@@ -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);
index 01126a3..22c0bf0 100644 (file)
@@ -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());
index 8f3943b..7722237 100644 (file)
@@ -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
index fa1161f..499dba6 100644 (file)
@@ -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
index 51bdb27..a8129f9 100644 (file)
@@ -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
index a79836c..84ebe4c 100755 (executable)
@@ -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"