public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Nick Clifton <nickc@redhat.com>
To: hjl.tools@gmail.com, binutils@sourceware.org
Cc: siddhesh@redhat.com
Subject: RFC: ld: Add --text-section-ordering-file (version 2)
Date: Thu, 25 Apr 2024 14:01:01 +0100	[thread overview]
Message-ID: <87edat7g1e.fsf@redhat.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 2922 bytes --]

Hi Guys,

  Attached is a patch to add a --section-ordering-file option to the BFD
  linker.  It is based upon H.J.'s original patch, but extended so that
  it will work with multiple output sections.

  There are a couple of points that I feel I should highlight:

  * The option only works in conjunction with a modified linker script.
  
    In particular the script must have: "INCLUDE section-ordering-file"
    statements in it, wherever it wants section ordering to be allowed.
    This statement can appear multiple times in a linker script,
    although it would not make sense to have it appear more than once in
    any given output section.  Here is an example:
    
      SECTIONS
      {
        .text : {
          INCLUDE section-ordering-file
          *(.text)
        }
        .data : {
          INCLUDE section-ordering-file
          *(.data)
        }
      }
    
  * H.J's original version allowed for linker script like
    "filename(section)" syntax to be used to name sections, eg:
    "*(.text.*)", as well as a simpler "section name regexp", eg
    ".text.*", to be used.  This version only supports the latter
    format.

    In addition H.J.'s syntax allowed for abbreviated section names to
    match.  So ".t*t" would match any section starting with ".t" and
    ending with "t" and would put it into the .text section.  In this
    version however the output section is selected based upon matching
    the fixed part at the start of the pattern with the output section.
    So ".t*t" would only work if the output section was called ".t".

    To help compensate for this, and to allow arbitrary input sections
    to be mapped to specific output sections, the output section name
    can be provided as if it were a filename.  So .foo(.bar) would map
    all sections called .bar to the output section .foo, but only if the
    linker script has an output section called .foo, and only if that
    output section declaration includes a INCLUDE section-ordering-file
    statement.
    
    Perhaps an example will make things clearer.  If the above linker
    script is used and the section ordering file contains:

      # A comment - this will be ignored.
      .text.hot .text.cold .text.warm
      .data.big
      .data(.bar)
      .text.foo*
      .ignore(.me)

    This is roughly equivalent to a linker script that looks like this:

      SECTIONS
      {
        .text : {
          *(.text.hot)
          *(.text.cold)
          *(.text.warm)
          *(.text.foo*)
          *(.text)
        }
        .data : {
          *(.data.big)
          *(.bar)
          *(.data)
        }
      }

    Note - the linker will not warn about entries in the section
    ordering file that do not match an output section name.  So in the
    above example the ".ignore(.me)" entry will not generate a warning
    about it not being used.

  Thoughts, comments, etc ?

Cheers
  Nick


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: section-ordering-file.patch --]
[-- Type: text/x-patch, Size: 47828 bytes --]

diff --git a/ld/NEWS b/ld/NEWS
index f70d2157339..458f6562ca0 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -2,6 +2,9 @@
 
 * Add -plugin-save-temps to store plugin intermediate files permanently.
 
+* Add the linker option, --section-ordering-file=FILE, for ELF and
+  PE COFF linker to specify the input section order.
+
 Changes in 2.42:
 
 * Add -z mark-plt/-z nomark-plt options to x86-64 ELF linker to mark PLT
diff --git a/ld/ld.h b/ld/ld.h
index fcdd9a2c083..81e9ee03387 100644
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -319,8 +319,20 @@ typedef struct
 
   /* Compress DWARF debug sections.  */
   enum compressed_debug_section_type compress_debug;
+
+  /* The optional section ordering file.  */
+  const char *section_ordering_file;
+
 } ld_config_type;
 
+/* Any "INPUT <filename>" directive inside a linekr script that uses
+   SECTION_ORDERING_FILE as its filename is actually a indicator that
+   the config.section_ordering_file parameter should be processed and
+   inserted.  */
+#define SECTION_ORDERING_FILE_1 "section-ordering-file"
+/* Also accept the name with underscores instead of dashes.  */
+#define SECTION_ORDERING_FILE_2 "section_ordering_file"
+
 extern ld_config_type config;
 
 extern FILE * saved_script_handle;
diff --git a/ld/ld.texi b/ld/ld.texi
index ca9574dfc71..a6f04c8a457 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -2552,6 +2552,105 @@ patterns in the linker script.
 This option will apply @code{SORT_BY_ALIGNMENT} to all wildcard section
 patterns in the linker script.
 
+@kindex --section-ordering-file=@file{file}
+@item --section-ordering-file=@file{file}
+This option gives the linker a file which tells it how to order
+specific input sections when placing them in an output section.
+
+The input file consists of one or more entries separated by white
+space and/or line separators.  Blank lines and line whose
+first non-whitespace character is a hash (@samp{#}), are ignored.
+
+Each entry in the section ordering file is either a section name, a
+section name regular expression, or an output section name followed by
+a list of section name patterns enclosed in parentheses.
+
+A section name attempts to map any input section matching that name to
+the output section that starts with the same prefix as the input
+section.  So for example @samp{.text.hot} maps all input sections
+called @samp{.text.hot} to the output section @samp{.text}.  Note -
+this mapping will only work if the linker script being used has
+specified that the particular output section allows section ordering
+input.  See below for more details.
+
+A section name regular expression entry matches multiple input
+sections to the output section whose name starts of the fixed part of
+the expression.
+
+A section name followed by a list of section name expressions enclosed
+inside parentheses maps the section name expressions to the output
+section named first.  So for example @samp{.data(.foo)} maps all
+incoming @samp{.foo} sections to the @samp{.data} output section.
+Note - if there are multiple section names or section name patterns
+inside the parenthesised list, the order of those sections relative to
+each other is not guaranteed.
+
+Most importantly however the order in which entries occur in the
+section ordering file will be preserved, within the output section to
+which they are mapped.
+
+Here is an example:
+
+@smallexample
+  # A comment
+  .text.hot .text.cold .text.warm
+  .data.big
+  .data(.bar)
+  .text.foo*
+@end smallexample
+
+This is roughly equivalent to a linker script that looks like this:
+
+@smallexample
+  SECTIONS
+  @{
+    .text : @{
+      *(.text.hot)
+      *(.text.cold)
+      *(.text.warm)
+      *(.text.foo*)
+      *(.text)
+      @}
+    .data : @{
+      *(.data.big)
+      *(.bar)
+      *(.data)
+      @}
+  @}
+@end smallexample
+
+Note - the syntax used in the section ordering file is similar to, but
+different from the syntax used in linker scripts.
+
+Note - this option works in conjunction with the linker script being
+used by the linker.  In particular the linker script must use special
+directives to indicate where the section order file's mappings should
+be placed.  So the above example would only work if the linker script
+looked something like this:
+
+@smallexample
+  SECTIONS
+  @{
+    .text : @{
+       INCLUDE section-ordering-file
+       *(.text)
+       @}
+    .data : @{
+       INCLUDE section-ordering-file
+       *(.data)
+       @}
+   @}
+@end smallexample
+
+Note - the @samp{--section-ordering-file} option controls the order of
+input sections being mapped into an output section.  It does not
+control the order of output sections in relation to each other.
+
+If the @option{verbose} option is enabled, the contents of the section
+ordering file will be reported.
+
+This option is supported only in ELF and PE COFF linkers.
+
 @kindex --spare-dynamic-tags
 @item --spare-dynamic-tags=@var{count}
 This option specifies the number of empty slots to leave in the
@@ -4188,6 +4287,13 @@ with the @option{-L} option.  You can nest calls to @code{INCLUDE} up to
 You can place @code{INCLUDE} directives at the top level, in @code{MEMORY} or
 @code{SECTIONS} commands, or in output section descriptions.
 
+Note - there is a special case for @code{INCLUDE} directives found
+inside the @code{SECTION} command.  If the @var{filename} is
+@var{section_ordering_file} or @var{section-ordering-file} then this
+indicates that the contents of the file specified by the
+@option{--section-ordering-file} option should be used at that
+particular point in the script.
+
 @item INPUT(@var{file}, @var{file}, @dots{})
 @itemx INPUT(@var{file} @var{file} @dots{})
 @kindex INPUT(@var{files})
diff --git a/ld/ldfile.c b/ld/ldfile.c
index dc9875d8813..991affbc44d 100644
--- a/ld/ldfile.c
+++ b/ld/ldfile.c
@@ -736,7 +736,7 @@ ldfile_open_file (lang_input_statement_type *entry)
 /* Try to open NAME.  */
 
 static FILE *
-try_open (const char *name, bool *sysrooted)
+try_open (const char *name, const char *orig_name, bool *sysrooted)
 {
   FILE *result;
 
@@ -750,10 +750,44 @@ try_open (const char *name, bool *sysrooted)
 
   if (verbose)
     {
-      if (result == NULL)
-	info_msg (_("cannot find script file %s\n"), name);
+      if (config.section_ordering_file != NULL
+	  && strcmp (orig_name, config.section_ordering_file) == 0)
+	{
+	  static bool displayed_ordering_file = false;
+
+	  if (displayed_ordering_file)
+	    ;
+	  else if (result == NULL)
+	    info_msg (_("cannot find section ordering file: %s\n"),
+		      name);
+	  else
+	    {
+	      static const int ld_bufsz = 8193;
+	      size_t n;
+	      char *buf = (char *) xmalloc (ld_bufsz);
+
+	      info_msg (_("opened section ordering file: %s\n"), name);
+	      info_msg ("==================================================\n");
+
+	      while ((n = fread (buf, 1, ld_bufsz - 1, result)) > 0)
+		{
+		  buf[n] = 0;
+		  info_msg ("%s", buf);
+		}
+	      rewind (result);
+	      free (buf);
+
+	      info_msg ("==================================================\n\n");
+	      displayed_ordering_file = true;
+	    }
+	}
       else
-	info_msg (_("opened script file %s\n"), name);
+	{
+	  if (result == NULL)
+	    info_msg (_("cannot find script file %s\n"), name);
+	  else
+	    info_msg (_("opened script file %s\n"), name);
+	}
     }
 
   return result;
@@ -832,7 +866,7 @@ ldfile_find_command_file (const char *name,
   if (!default_only)
     {
       /* First try raw name.  */
-      result = try_open (name, sysrooted);
+      result = try_open (name, name, sysrooted);
       if (result != NULL)
 	return result;
     }
@@ -859,7 +893,7 @@ ldfile_find_command_file (const char *name,
        search = search->next)
     {
       path = concat (search->name, slash, name, (const char *) NULL);
-      result = try_open (path, sysrooted);
+      result = try_open (path, name, sysrooted);
       free (path);
       if (result)
 	break;
@@ -871,7 +905,8 @@ ldfile_find_command_file (const char *name,
   return result;
 }
 
-enum script_open_style {
+enum script_open_style
+{
   script_nonT,
   script_T,
   script_defaultT
@@ -908,6 +943,40 @@ ldfile_open_command_file_1 (const char *name, enum script_open_style open_how)
 	}
     }
 
+  /* Don't allow nested INCLUDEs in the section ordering file.  */
+  if (in_section_ordering_file)
+    {
+      einfo (_("%F%P: error: 'INCLUDE %s' found in the section "
+	       "ordering file: '%s'\n"), name, config.section_ordering_file);
+      return;
+    }
+
+  if (strcmp (name, SECTION_ORDERING_FILE_1) == 0
+      || strcmp (name, SECTION_ORDERING_FILE_2) == 0)    
+    {
+      /* Support
+
+	 INCLUDE section_ordering_file;
+
+	 in input sections in linker script.  */
+      if (config.section_ordering_file == NULL)
+	{
+	  /* Skip if the section ordering file isn't specified.  */
+	  lex_push_file (NULL, name, false);
+	  return;
+	}
+
+      /* FIXME: Check that we are inside the SECTIONS part of the script.  */
+
+      /* Load the section ordering file.  */
+      name = config.section_ordering_file;
+
+      /* Set the in the section ordering file marker.  */
+      in_section_ordering_file = true;
+    }
+  else
+    in_section_ordering_file = false;
+
   /* FIXME: This memory is never freed, but that should not really matter.
      It will be released when the linker exits, and it is unlikely to ever
      be more than a few tens of bytes.  */
@@ -932,7 +1001,12 @@ ldfile_open_command_file_1 (const char *name, enum script_open_style open_how)
 
   lineno = 1;
 
-  saved_script_handle = ldlex_input_stack;
+  /* Clear the end of the include file marker.  */
+  seen_eof_include_file = false;
+
+  /* The section ordering file isn't a real linker script file.  */
+  if (!in_section_ordering_file)
+    saved_script_handle = ldlex_input_stack;
 }
 
 /* Open command file NAME in the current directory, -L directories,
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 54d1af62ebe..61d2f5153ab 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -689,7 +689,9 @@ wild_sort (lang_wild_statement_type *wild,
 	 looking at the sections for this file.  */
 
       /* Find the correct node to append this section.  */
-      if (sec && sec->spec.sorted != none && sec->spec.sorted != by_none
+      if (sec
+	  && sec->spec.sorted != none
+	  && sec->spec.sorted != by_none
 	  && compare_section (sec->spec.sorted, section, (*tree)->section, sec->spec.reversed) < 0)
 	tree = &((*tree)->left);
       else
@@ -957,7 +959,7 @@ resolve_wild_sections (lang_input_statement_type *file)
       const char *sname = bfd_section_name (s);
       char c = 1;
       struct prefixtree *t = ptroot;
-      //printf (" YYY consider %s of %s\n", sname, file->the_bfd->filename);
+
       do
 	{
 	  if (t->stmt)
@@ -966,7 +968,6 @@ resolve_wild_sections (lang_input_statement_type *file)
 	      for (sl = t->stmt; sl; sl = sl->next)
 		{
 		  walk_wild_section_match (sl->stmt, file, s);
-		  //printf ("   ZZZ maybe place into %p\n", sl->stmt);
 		}
 	    }
 	  if (!c)
@@ -985,7 +986,6 @@ resolve_wilds (void)
 {
   LANG_FOR_EACH_INPUT_STATEMENT (f)
     {
-      //printf("XXX   %s\n", f->filename);
       if (f->the_bfd == NULL
 	  || !bfd_check_format (f->the_bfd, bfd_archive))
 	resolve_wild_sections (f);
@@ -8515,12 +8515,101 @@ lang_add_wild (struct wildcard_spec *filespec,
 
   if (filespec != NULL && filespec->name != NULL)
     {
-      if (strcmp (filespec->name, "*") == 0)
-	filespec->name = NULL;
-      else if (!wildcardp (filespec->name))
-	lang_has_input_file = true;
+      if (in_section_ordering_file)
+	{
+	  if (filespec->sorted != none
+	      || filespec->exclude_name_list != NULL
+	      || filespec->section_flag_list != NULL
+	      || filespec->reversed)
+	    {
+	      einfo (_("%F%P: error: \
+sorting, excluding, reversing and flag selection is not supported in section ordering file entries\n"));
+	    }
+	  else if (current_section == NULL)
+	    {
+	      einfo (_("%F%P: error: \
+using a section ordering file outside of an output section definition is not supported\n"));
+	    }
+	  else if (section_list != NULL)
+	    {
+	      /* We need a way to include input sections whose names do not
+		 start with the output section's name.  We do this by accepting
+		 entries of the form "<output-section-name> ( <input-section-regexp> )"
+		 The <output-section-name> should not be a regexp.  */
+	      if (strcmp (filespec->name, current_section->name) == 0)
+		{
+		  /* Convert .text(.bar) into *(.bar).  */
+		  filespec->name = NULL;
+		  goto cont;
+		}
+
+	      /* FIXME: We have no way of detecting if an entry in the section
+		 ordering file does not match any output section.  */
+	    }
+	  else if (strncmp (filespec->name, current_section->name,
+			    strlen (current_section->name)))
+	    {
+	      /* Exclude this entry from this section.
+		 Since we have a single section ordering file, but we want it
+		 to be able to provide the ordering for multiple output
+		 sections, we match entries to output sections.  So for
+		 example if the ordering file contains:
+		   .text.foo
+		   .data.bar
+		   .text.b*
+		   .data.z*
+		 Then we add the .text.foo and .text.b* patterns to the .text
+		 output section (in that order) and the .data.bar and .data.z*
+		 patterns to the .data output section.
+
+		 This behaviour relies upon the linker script containing
+		 "INCLUDE section-ordering-file" directives in all of the
+		 output sections that it wants to be able to be affected by
+		 the --section-ordering-file option.  */
+	      ;
+
+	      /* FIXME: We have no way of detecting if an entry in the section
+		 ordering file does not match any output section.  */
+	    }
+	  else
+	    {
+	      /* A section ordering file entry looks like a filename
+		 without a section list.  Convert the filename into
+		 a section name and create a wild card as the file
+		 name.  */
+	      struct wildcard_list *single_section = XCNEW (struct wildcard_list);
+
+	      single_section->spec.name = filespec->name;
+	      single_section->spec.sorted = none;
+	      /* A NULL indicates the wild card file name, "*".  */
+	      filespec->name = NULL;
+	      section_list = single_section;
+
+	      /* Carry on processing the statement.  */
+	      goto cont;
+	    }
+	  
+	  if (seen_eof_include_file)
+	    in_section_ordering_file = false;
+
+	  return;
+	}
+      else
+	{
+	  if (strcmp (filespec->name, "*") == 0)
+	    filespec->name = NULL;
+	  else if (!wildcardp (filespec->name))
+	    lang_has_input_file = true;
+	}
     }
 
+ cont:
+  /* NB: Clear the in the section ordering file marker after
+     processing the last entry when the end of the section
+     ordering file is reached.  */
+  if (in_section_ordering_file && seen_eof_include_file)
+    in_section_ordering_file = false;
+
   new_stmt = new_stat (lang_wild_statement, stat_ptr);
   new_stmt->filename = NULL;
   new_stmt->filenames_sorted = false;
diff --git a/ld/ldlex.h b/ld/ldlex.h
index d575562a357..39454cc764c 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -68,6 +68,7 @@ enum option_values
   OPTION_TASK_LINK,
   OPTION_TBSS,
   OPTION_TDATA,
+  OPTION_SECTION_ORDERING_FILE,
   OPTION_TTEXT,
   OPTION_TTEXT_SEGMENT,
   OPTION_TRODATA_SEGMENT,
@@ -485,6 +486,8 @@ extern input_type parser_input;
 
 extern unsigned int lineno;
 extern const char *lex_string;
+extern bool in_section_ordering_file;
+extern bool seen_eof_include_file;
 
 /* In ldlex.l.  */
 extern int yylex (void);
diff --git a/ld/ldlex.l b/ld/ldlex.l
index e113c90812b..113e4126d0b 100644
--- a/ld/ldlex.l
+++ b/ld/ldlex.l
@@ -43,6 +43,12 @@ input_type parser_input;
 /* Line number in the current input file.  */
 unsigned int lineno;
 
+/* True if the current input file is the section ordering file.  */
+bool in_section_ordering_file = false;
+
+/* True if the end of the include file is reached.  */
+bool seen_eof_include_file = false;
+
 /* The string we are currently lexing, or NULL if we are reading a
    file.  */
 const char *lex_string = NULL;
@@ -487,6 +493,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
 
   lineno = lineno_stack[include_stack_ptr];
   input_flags.sysrooted = sysrooted_stack[include_stack_ptr];
+  seen_eof_include_file = true;
 
   return END;
 }
diff --git a/ld/lexsup.c b/ld/lexsup.c
index dad3b6059ed..15a20fe86ac 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -487,6 +487,9 @@ static const struct ld_option ld_options[] =
   { {"sort-section", required_argument, NULL, OPTION_SORT_SECTION},
     '\0', N_("name|alignment"),
     N_("Sort sections by name or maximum alignment"), TWO_DASHES },
+  { {"section-ordering-file", required_argument, NULL, OPTION_SECTION_ORDERING_FILE},
+    '\0', N_("FILE"),
+    N_("Sort sections by statements in FILE"), TWO_DASHES },
   { {"spare-dynamic-tags", required_argument, NULL, OPTION_SPARE_DYNAMIC_TAGS},
     '\0', N_("COUNT"), N_("How many tags to reserve in .dynamic section"),
     TWO_DASHES },
@@ -673,6 +676,7 @@ parse_args (unsigned argc, char **argv)
     dynamic_list
   } opt_dynamic_list = dynamic_list_unset;
   struct bfd_elf_dynamic_list *export_list = NULL;
+  bool seen_linker_script = false;
 
   shortopts = (char *) xmalloc (OPTION_COUNT * 3 + 2);
   longopts = (struct option *)
@@ -1400,6 +1404,12 @@ parse_args (unsigned argc, char **argv)
 	    einfo (_("%F%P: invalid section sorting option: %s\n"),
 		   optarg);
 	  break;
+	case OPTION_SECTION_ORDERING_FILE:
+	  if (seen_linker_script)
+	    einfo (_("%F%P: --section-ordering-file must be placed"
+		     " before -T/--script\n"));
+	  config.section_ordering_file = optarg;
+	  break;
 	case OPTION_STATS:
 	  config.stats = true;
 	  break;
@@ -1416,6 +1426,7 @@ parse_args (unsigned argc, char **argv)
 	  ++trace_files;
 	  break;
 	case 'T':
+	  seen_linker_script = true;
 	  previous_script_handle = saved_script_handle;
 	  ldfile_open_script_file (optarg);
 	  parser_input = input_script;
diff --git a/ld/scripttempl/arclinux.sc b/ld/scripttempl/arclinux.sc
index 36ba5a664d3..eabbb90c3d5 100644
--- a/ld/scripttempl/arclinux.sc
+++ b/ld/scripttempl/arclinux.sc
@@ -487,11 +487,12 @@ cat <<EOF
   .text         ${RELOCATING-0} :
   {
     ${RELOCATING+${TEXT_START_SYMBOLS}}
-    ${RELOCATING+*(.text.unlikely .text.*_unlikely .text.unlikely.*)}
-    ${RELOCATING+*(.text.exit .text.exit.*)}
+    ${RELOCATING+INCLUDE section_ordering_file}
     ${RELOCATING+*(.text.startup .text.startup.*)}
     ${RELOCATING+*(.text.hot .text.hot.*)}
     ${RELOCATING+*(SORT(.text.sorted.*))}
+    ${RELOCATING+*(.text.unlikely .text.*_unlikely .text.unlikely.*)}
+    ${RELOCATING+*(.text.exit .text.exit.*)}
     *(.text .stub${RELOCATING+ .text.* .gnu.linkonce.t.*})
     /* .gnu.warning sections are handled specially by elf.em.  */
     *(.gnu.warning)
@@ -598,6 +599,7 @@ cat <<EOF
   .data         ${RELOCATING-0} :
   {
     ${RELOCATING+${DATA_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data${RELOCATING+ .data.* .gnu.linkonce.d.*})
     ${CONSTRUCTING+SORT(CONSTRUCTORS)}
   }
diff --git a/ld/scripttempl/avr.sc b/ld/scripttempl/avr.sc
index 329d57e2849..bbfee834fc3 100644
--- a/ld/scripttempl/avr.sc
+++ b/ld/scripttempl/avr.sc
@@ -244,6 +244,7 @@ SECTIONS
     KEEP (*(.init8))
     *(.init9)  /* Call main().  */
     KEEP (*(.init9))}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+. = ALIGN(2);
     *(.text.*)
@@ -305,6 +306,7 @@ cat <<EOF
   .data        ${RELOCATING-0} :
   {
     ${RELOCATING+ PROVIDE (__data_start = .) ; }
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data)
     ${RELOCATING+ *(.data*)
     *(.gnu.linkonce.d*)}
diff --git a/ld/scripttempl/dlx.sc b/ld/scripttempl/dlx.sc
index 8dcbf300c56..d606535224c 100644
--- a/ld/scripttempl/dlx.sc
+++ b/ld/scripttempl/dlx.sc
@@ -22,12 +22,14 @@ SECTIONS
   .text :
   {
     ${RELOCATING+CREATE_OBJECT_SYMBOLS}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+etext = ${DATA_ALIGNMENT};}
   }
   ${RELOCATING+. = ${DATA_ALIGNMENT};}
   .data :
   {
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data)
     ${CONSTRUCTING+CONSTRUCTORS}
     ${RELOCATING+edata  =  .;}
diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc
index d5022fa502f..64b1d8b3305 100644
--- a/ld/scripttempl/elf.sc
+++ b/ld/scripttempl/elf.sc
@@ -553,11 +553,12 @@ cat <<EOF
   .text         ${RELOCATING-0} :
   {
     ${RELOCATING+${TEXT_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section-ordering-file}
+    ${RELOCATING+*(.text.hot .text.hot.*)}
+    ${RELOCATING+*(SORT(.text.sorted.*))}
     ${RELOCATING+*(.text.unlikely .text.*_unlikely .text.unlikely.*)}
     ${RELOCATING+*(.text.exit .text.exit.*)}
     ${RELOCATING+*(.text.startup .text.startup.*)}
-    ${RELOCATING+*(.text.hot .text.hot.*)}
-    ${RELOCATING+*(SORT(.text.sorted.*))}
     *(.text .stub${RELOCATING+ .text.* .gnu.linkonce.t.*})
     /* .gnu.warning sections are handled specially by elf.em.  */
     *(.gnu.warning)
@@ -672,6 +673,7 @@ cat <<EOF
   .data         ${RELOCATING-0}${RELOCATING+${DATA_SECTION_ALIGNMENT}} :
   {
     ${RELOCATING+${DATA_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section-ordering-file}
     *(.data${RELOCATING+ .data.* .gnu.linkonce.d.*})
     ${CONSTRUCTING+SORT(CONSTRUCTORS)}
   }
diff --git a/ld/scripttempl/elf32cr16.sc b/ld/scripttempl/elf32cr16.sc
index 3e7d92a4f34..19ebde72510 100644
--- a/ld/scripttempl/elf32cr16.sc
+++ b/ld/scripttempl/elf32cr16.sc
@@ -81,6 +81,7 @@ SECTIONS
   .text :
   {
     __TEXT_START = .;
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text) *(.text.*) *(.gnu.linkonce.t.*)
     __TEXT_END = .;
   }${RELOCATING+ > rom}
@@ -131,6 +132,7 @@ SECTIONS
   .data :
   {
     __DATA_START = .;
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data_4) *(.data_2) *(.data_1) *(.data) *(.data.*) *(.gnu.linkonce.d.*)
     __DATA_END = .;
   }${RELOCATING+ > ram AT > rom}
diff --git a/ld/scripttempl/elf32crx.sc b/ld/scripttempl/elf32crx.sc
index 1b1316676a7..a1a8186a371 100644
--- a/ld/scripttempl/elf32crx.sc
+++ b/ld/scripttempl/elf32crx.sc
@@ -77,6 +77,7 @@ SECTIONS
   .text :
   {
     __TEXT_START = .;
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text) *(.text.*) *(.gnu.linkonce.t.*)
     __TEXT_END = .;
   } > rom
@@ -129,6 +130,7 @@ SECTIONS
   .data :
   {
     __DATA_START = .;
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data_4) *(.data_2) *(.data_1) *(.data) *(.data.*) *(.gnu.linkonce.d.*)
     __DATA_END = .;
   } > ram AT > rom
diff --git a/ld/scripttempl/elf32msp430.sc b/ld/scripttempl/elf32msp430.sc
index bed0d673238..2c638f15b00 100644
--- a/ld/scripttempl/elf32msp430.sc
+++ b/ld/scripttempl/elf32msp430.sc
@@ -163,6 +163,7 @@ SECTIONS
     *(.lower.text.* .lower.text)
 
     . = ALIGN(2);}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+. = ALIGN(2);
     *(.text.*)
@@ -260,6 +261,7 @@ SECTIONS
     PROVIDE (__data_start = .) ;
     PROVIDE (__datastart = .) ;
 
+    ${RELOCATING+INCLUDE section_ordering_file}
     KEEP (*(.jcr))
     *(.data.rel.ro.local) *(.data.rel.ro*)
     *(.dynamic)
diff --git a/ld/scripttempl/elf64bpf.sc b/ld/scripttempl/elf64bpf.sc
index ca62d7c88e0..0ea9b4a9064 100644
--- a/ld/scripttempl/elf64bpf.sc
+++ b/ld/scripttempl/elf64bpf.sc
@@ -508,11 +508,12 @@ cat <<EOF
   .text         ${RELOCATING-0} :
   {
     ${RELOCATING+${TEXT_START_SYMBOLS}}
-    ${RELOCATING+*(.text.unlikely .text.*_unlikely .text.unlikely.*)}
-    ${RELOCATING+*(.text.exit .text.exit.*)}
+    ${RELOCATING+INCLUDE section_ordering_file}
     ${RELOCATING+*(.text.startup .text.startup.*)}
     ${RELOCATING+*(.text.hot .text.hot.*)}
     ${RELOCATING+*(SORT(.text.sorted.*))}
+    ${RELOCATING+*(.text.unlikely .text.*_unlikely .text.unlikely.*)}
+    ${RELOCATING+*(.text.exit .text.exit.*)}
     *(.text .stub${RELOCATING+ .text.* .gnu.linkonce.t.*})
     /* .gnu.warning sections are handled specially by elf.em.  */
     *(.gnu.warning)
@@ -621,6 +622,7 @@ cat <<EOF
   .data         ${RELOCATING-0} :
   {
     ${RELOCATING+${DATA_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data${RELOCATING+ .data.* .gnu.linkonce.d.*})
     ${CONSTRUCTING+SORT(CONSTRUCTORS)}
   }
diff --git a/ld/scripttempl/elf64hppa.sc b/ld/scripttempl/elf64hppa.sc
index 6bde304dd27..991219b8bd2 100644
--- a/ld/scripttempl/elf64hppa.sc
+++ b/ld/scripttempl/elf64hppa.sc
@@ -412,6 +412,7 @@ cat <<EOF
   .text         ${RELOCATING-0} :
   {
     ${RELOCATING+${TEXT_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text .stub${RELOCATING+ .text.* .gnu.linkonce.t.*})
     /* .gnu.warning sections are handled specially by elf.em.  */
     *(.gnu.warning)
@@ -475,6 +476,7 @@ cat <<EOF
   .data         ${RELOCATING-0} :
   {
     ${RELOCATING+${DATA_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data${RELOCATING+ .data.* .gnu.linkonce.d.*})
     ${CONSTRUCTING+SORT(CONSTRUCTORS)}
   }
diff --git a/ld/scripttempl/elfarc.sc b/ld/scripttempl/elfarc.sc
index 1ae0248a900..bf98c4464a1 100644
--- a/ld/scripttempl/elfarc.sc
+++ b/ld/scripttempl/elfarc.sc
@@ -288,6 +288,7 @@ cat <<EOF
   .text         ${RELOCATING-0} :
   {
     ${RELOCATING+${TEXT_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text .stub${RELOCATING+ .text.* .gnu.linkonce.t.*})
     /* .gnu.warning sections are handled specially by elf.em.  */
     *(.gnu.warning)
@@ -337,6 +338,7 @@ cat <<EOF
   .data         ${RELOCATING-0} :
   {
     ${RELOCATING+${DATA_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data${RELOCATING+ .data.* .gnu.linkonce.d.*})
     ${CONSTRUCTING+SORT(CONSTRUCTORS)}
   }
diff --git a/ld/scripttempl/elfarcv2.sc b/ld/scripttempl/elfarcv2.sc
index 3054e4c62f3..05c04662b32 100644
--- a/ld/scripttempl/elfarcv2.sc
+++ b/ld/scripttempl/elfarcv2.sc
@@ -192,6 +192,7 @@ SECTIONS
 
     /* Remaining code.  */
     ${RELOCATING+ . = ALIGN(4);}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text .stub${RELOCATING+ .text.* .gnu.linkonce.t.*})
     /* .gnu.warning sections are handled specially by elf.em.  */
     *(.gnu.warning)
@@ -253,6 +254,7 @@ SECTIONS
   .data	${RELOCATING-0} :
   {
     ${RELOCATING+ PROVIDE (__data_start = .) ; }
+    ${RELOCATING+INCLUDE section_ordering_file}
     /* --gc-sections will delete empty .data. This leads to wrong start
        addresses for subsequent sections because -Tdata= from the command
        line will have no effect, see PR13697.  Thus, keep .data  */
diff --git a/ld/scripttempl/elfd10v.sc b/ld/scripttempl/elfd10v.sc
index 1ecf4a19092..2c4ed68bf63 100644
--- a/ld/scripttempl/elfd10v.sc
+++ b/ld/scripttempl/elfd10v.sc
@@ -109,6 +109,7 @@ SECTIONS
     KEEP (*(SORT_NONE(.init.*)))
     KEEP (*(SORT_NONE(.fini)))
     KEEP (*(SORT_NONE(.fini.*)))}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+*(.text.*)}
     /* .gnu.warning sections are handled specially by elf.em.  */
@@ -132,6 +133,7 @@ SECTIONS
   .data  ${RELOCATING-0} :
   {
     ${RELOCATING+${DATA_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data)
     ${RELOCATING+*(.data.*)
     *(.gnu.linkonce.d*)}
diff --git a/ld/scripttempl/elfd30v.sc b/ld/scripttempl/elfd30v.sc
index ed0c412edc8..2cfb937515e 100644
--- a/ld/scripttempl/elfd30v.sc
+++ b/ld/scripttempl/elfd30v.sc
@@ -125,6 +125,7 @@ SECTIONS
   /* Internal text space or external memory */
   .text :
   {
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+*(.gnu.linkonce.t*)
     KEEP (*(SORT_NONE(.fini)))
@@ -150,6 +151,7 @@ SECTIONS
 
   .data		${RELOCATING-0} :
   {
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data)
     ${RELOCATING+*(.gnu.linkonce.d*)}
     ${CONSTRUCTING+CONSTRUCTORS}
diff --git a/ld/scripttempl/elfm68hc11.sc b/ld/scripttempl/elfm68hc11.sc
index b122da0e32a..73634062e96 100644
--- a/ld/scripttempl/elfm68hc11.sc
+++ b/ld/scripttempl/elfm68hc11.sc
@@ -318,6 +318,7 @@ SECTIONS
     /* Put startup code at beginning so that _start keeps same address.  */
     ${RELOCATING+${STARTUP_CODE}}
 
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+*(.text.*)}
     /* .gnu.warning sections are handled specially by elf.em.  */
@@ -378,6 +379,7 @@ SECTIONS
     ${RELOCATING+__data_section_start = .;}
     ${RELOCATING+PROVIDE (__data_section_start = .);}
 
+    ${RELOCATING+INCLUDE section_ordering_file}
     ${RELOCATING+${DATA_START_SYMBOLS}}
     ${RELOCATING+*(.sdata)}
     *(.data)
diff --git a/ld/scripttempl/elfm68hc12.sc b/ld/scripttempl/elfm68hc12.sc
index 47410a95f46..78c9db5ceb8 100644
--- a/ld/scripttempl/elfm68hc12.sc
+++ b/ld/scripttempl/elfm68hc12.sc
@@ -317,6 +317,7 @@ SECTIONS
     /* Put startup code at beginning so that _start keeps same address.  */
     ${RELOCATING+${STARTUP_CODE}}
 
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+*(.text.*)}
     /* .gnu.warning sections are handled specially by elf.em.  */
@@ -379,6 +380,7 @@ SECTIONS
     ${RELOCATING+__data_section_start = .;}
     ${RELOCATING+PROVIDE (__data_section_start = .);}
 
+    ${RELOCATING+INCLUDE section_ordering_file}
     ${RELOCATING+${DATA_START_SYMBOLS}}
     ${RELOCATING+*(.sdata)}
     *(.data)
diff --git a/ld/scripttempl/elfm9s12z.sc b/ld/scripttempl/elfm9s12z.sc
index 271d218835b..861096cbba1 100644
--- a/ld/scripttempl/elfm9s12z.sc
+++ b/ld/scripttempl/elfm9s12z.sc
@@ -303,6 +303,7 @@ SECTIONS
     /* Put startup code at beginning so that _start keeps same address.  */
     ${RELOCATING+${STARTUP_CODE}}
 
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+*(.text.*)}
     /* .gnu.warning sections are handled specially by elf.em.  */
@@ -368,6 +369,7 @@ SECTIONS
     ${RELOCATING+__data_section_start = .;}
     ${RELOCATING+PROVIDE (__data_section_start = .);}
 
+    ${RELOCATING+INCLUDE section_ordering_file}
     ${RELOCATING+${DATA_START_SYMBOLS}}
     ${RELOCATING+*(.sdata)}
     *(.data)
diff --git a/ld/scripttempl/elfmicroblaze.sc b/ld/scripttempl/elfmicroblaze.sc
index 88abe4f10ba..13649908e24 100644
--- a/ld/scripttempl/elfmicroblaze.sc
+++ b/ld/scripttempl/elfmicroblaze.sc
@@ -79,6 +79,7 @@ SECTIONS
 
   ${RELOCATING+ _ftext  =  .;}
   .text : {
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+*(.text.*)}
     ${RELOCATING+*(.gnu.linkonce.t.*)}
@@ -135,6 +136,7 @@ SECTIONS
   ${RELOCATING+ . = ALIGN(4);}
   ${RELOCATING+ _fdata = .;}
   .data : {
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data)
     ${RELOCATING+*(.data.*)}
     ${RELOCATING+*(.gnu.linkonce.d.*)}
diff --git a/ld/scripttempl/elfxgate.sc b/ld/scripttempl/elfxgate.sc
index 4c25bc161f2..9f94220ad48 100644
--- a/ld/scripttempl/elfxgate.sc
+++ b/ld/scripttempl/elfxgate.sc
@@ -317,6 +317,7 @@ SECTIONS
     /* Put startup code at beginning so that _start keeps same address.  */
     ${RELOCATING+${STARTUP_CODE}}
 
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+*(.text.*)}
     /* .gnu.warning sections are handled specially by elf.em.  */
@@ -379,6 +380,7 @@ SECTIONS
     ${RELOCATING+__data_section_start = .;}
     ${RELOCATING+PROVIDE (__data_section_start = .);}
 
+    ${RELOCATING+INCLUDE section_ordering_file}
     ${RELOCATING+${DATA_START_SYMBOLS}}
     ${RELOCATING+*(.sdata)}
     *(.data)
diff --git a/ld/scripttempl/elfxtensa.sc b/ld/scripttempl/elfxtensa.sc
index 231f53b5f5b..5b3d7793cdc 100644
--- a/ld/scripttempl/elfxtensa.sc
+++ b/ld/scripttempl/elfxtensa.sc
@@ -418,6 +418,7 @@ cat <<EOF
     ${RELOCATING+${INIT_END}}
 
     ${RELOCATING+${TEXT_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.literal .text .stub${RELOCATING+ .literal.* .text.* .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*})
     /* .gnu.warning sections are handled specially by elf.em.  */
     *(.gnu.warning)
@@ -485,6 +486,7 @@ cat <<EOF
   .data         ${RELOCATING-0} :
   {
     ${RELOCATING+${DATA_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data${RELOCATING+ .data.* .gnu.linkonce.d.*})
     ${CONSTRUCTING+SORT(CONSTRUCTORS)}
   }
diff --git a/ld/scripttempl/ft32.sc b/ld/scripttempl/ft32.sc
index e52e75cd924..666664ab190 100644
--- a/ld/scripttempl/ft32.sc
+++ b/ld/scripttempl/ft32.sc
@@ -32,6 +32,7 @@ SECTIONS
 {
   .text :
   {
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text${RELOCATING+*})
     ${RELOCATING+*(.strings)
     *(._pm*)
@@ -43,6 +44,7 @@ SECTIONS
   ${CONSTRUCTING+${TORS}}
   .data	: ${RELOCATING+ AT (ADDR (.text) + SIZEOF (.text))}
   {
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data)
     ${RELOCATING+*(.rodata)
     *(.rodata*)
diff --git a/ld/scripttempl/i386beos.sc b/ld/scripttempl/i386beos.sc
index 6c512e67760..276f0dedfe5 100644
--- a/ld/scripttempl/i386beos.sc
+++ b/ld/scripttempl/i386beos.sc
@@ -60,6 +60,7 @@ SECTIONS
   {
     ${RELOCATING+ __text_start__ = . ;}
     ${RELOCATING+ KEEP (*(SORT_NONE(.init)))}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${R_TEXT}
     *(.glue_7t)
@@ -85,6 +86,7 @@ SECTIONS
   .data ${RELOCATING+BLOCK(__section_alignment__)} :
   {
     ${RELOCATING+__data_start__ = . ;}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data)
     *(.data2)
     ${R_DATA}
diff --git a/ld/scripttempl/i386go32.sc b/ld/scripttempl/i386go32.sc
index 9b992279e4e..f7c6109bdaa 100644
--- a/ld/scripttempl/i386go32.sc
+++ b/ld/scripttempl/i386go32.sc
@@ -34,6 +34,7 @@ ${RELOCATING+ENTRY (${ENTRY})}
 SECTIONS
 {
   .text ${RELOCATING+ ${TARGET_PAGE_SIZE}+SIZEOF_HEADERS} : {
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+*(.text.*)}
     ${RELOCATING+*(.gnu.linkonce.t*)}
@@ -58,6 +59,7 @@ SECTIONS
     __environ = . ;
     PROVIDE(_environ = .) ;
     LONG(0) ;
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data)
     ${RELOCATING+*(.data.*)}
 
diff --git a/ld/scripttempl/iq2000.sc b/ld/scripttempl/iq2000.sc
index e85aa2303ed..2a55ef7f7a0 100644
--- a/ld/scripttempl/iq2000.sc
+++ b/ld/scripttempl/iq2000.sc
@@ -297,6 +297,7 @@ cat <<EOF
   .text    ${RELOCATING-0} :
   {
     ${RELOCATING+${TEXT_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+*(.text.*)}
     *(.stub)
@@ -323,6 +324,7 @@ cat <<EOF
   .data  ${RELOCATING-0} :
   {
     ${RELOCATING+${DATA_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data)
     ${RELOCATING+*(.data.*)}
     ${RELOCATING+*(.gnu.linkonce.d.*)}
diff --git a/ld/scripttempl/mcorepe.sc b/ld/scripttempl/mcorepe.sc
index 3262102e85e..7a37a784d1c 100644
--- a/ld/scripttempl/mcorepe.sc
+++ b/ld/scripttempl/mcorepe.sc
@@ -66,6 +66,7 @@ SECTIONS
   .text ${RELOCATING+ __image_base__ + __section_alignment__ } :
   {
     ${RELOCATING+ KEEP (*(SORT_NONE(.init)))}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${R_TEXT}
     ${RELOCATING+ *(.text.*)}
@@ -91,6 +92,7 @@ SECTIONS
   .data ${RELOCATING+BLOCK(__section_alignment__)} :
   {
     ${RELOCATING+__data_start__ = . ;}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data)
     *(.data2)
     ${R_DATA}
diff --git a/ld/scripttempl/mep.sc b/ld/scripttempl/mep.sc
index 39e4d64857c..3bf5e0354aa 100644
--- a/ld/scripttempl/mep.sc
+++ b/ld/scripttempl/mep.sc
@@ -310,6 +310,7 @@ cat <<EOF
   .text         ${RELOCATING-0} :
   {
     ${RELOCATING+${TEXT_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text .stub${RELOCATING+ .text.* .gnu.linkonce.t.*})
     /* .gnu.warning sections are handled specially by elf.em.  */
     *(.gnu.warning)
@@ -369,6 +370,7 @@ cat <<EOF
   .data         ${RELOCATING-0} :
   {
     ${RELOCATING+${DATA_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data${RELOCATING+ .data.* .gnu.linkonce.d.*})
     ${CONSTRUCTING+SORT(CONSTRUCTORS)}
   }
diff --git a/ld/scripttempl/mmo.sc b/ld/scripttempl/mmo.sc
index e87a758eb90..ef946c8d2b7 100644
--- a/ld/scripttempl/mmo.sc
+++ b/ld/scripttempl/mmo.sc
@@ -30,6 +30,7 @@ SECTIONS
     ${RELOCATING+ KEEP (*(SORT_NONE(.init)))}
     ${RELOCATING+ PROVIDE (_init_end = .);}
 
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+*(.text.*)}
     ${RELOCATING+*(.gnu.linkonce.t*)}
@@ -87,6 +88,7 @@ SECTIONS
   {
     ${RELOCATING+ PROVIDE(__Sdata = .);}
 
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data);
     ${RELOCATING+*(.data.*)}
     ${RELOCATING+*(.gnu.linkonce.d*)}
diff --git a/ld/scripttempl/nds32elf.sc b/ld/scripttempl/nds32elf.sc
index 0f8366d91ac..13abb9fc0a4 100644
--- a/ld/scripttempl/nds32elf.sc
+++ b/ld/scripttempl/nds32elf.sc
@@ -434,11 +434,12 @@ cat <<EOF
   .text         ${RELOCATING-0} :
   {
     ${RELOCATING+${TEXT_START_SYMBOLS}}
-    ${RELOCATING+*(.text.unlikely .text.*_unlikely .text.unlikely.*)}
-    ${RELOCATING+*(.text.exit .text.exit.*)}
+    ${RELOCATING+INCLUDE section_ordering_file}
     ${RELOCATING+*(.text.startup .text.startup.*)}
     ${RELOCATING+*(.text.hot .text.hot.*)}
     ${RELOCATING+*(SORT(.text.sorted.*))}
+    ${RELOCATING+*(.text.unlikely .text.*_unlikely .text.unlikely.*)}
+    ${RELOCATING+*(.text.exit .text.exit.*)}
     *(.text .stub${RELOCATING+ .text.* .gnu.linkonce.t.*})
     /* .gnu.warning sections are handled specially by elf.em.  */
     *(.gnu.warning)
@@ -540,6 +541,7 @@ cat <<EOF
   .data         ${RELOCATING-0} :
   {
     ${RELOCATING+${DATA_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data${RELOCATING+ .data.* .gnu.linkonce.d.*})
     ${CONSTRUCTING+SORT(CONSTRUCTORS)}
   }
diff --git a/ld/scripttempl/pe.sc b/ld/scripttempl/pe.sc
index 70f5194b02f..60690b07f68 100644
--- a/ld/scripttempl/pe.sc
+++ b/ld/scripttempl/pe.sc
@@ -91,6 +91,7 @@ SECTIONS
   .text ${RELOCATING+ __image_base__ + ( __section_alignment__ < ${TARGET_PAGE_SIZE} ? . : __section_alignment__ )} :
   {
     ${RELOCATING+KEEP (*(SORT_NONE(.init)))}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${R_TEXT}
     ${RELOCATING+ *(.text.*)}
@@ -153,6 +154,7 @@ SECTIONS
   .data ${RELOCATING+BLOCK(__section_alignment__)} :
   {
     ${RELOCATING+__data_start__ = . ;}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data)
     ${RELOCATING+*(.data2)}
     ${R_DATA}
diff --git a/ld/scripttempl/pep.sc b/ld/scripttempl/pep.sc
index 63039f11574..23557104f51 100644
--- a/ld/scripttempl/pep.sc
+++ b/ld/scripttempl/pep.sc
@@ -92,6 +92,7 @@ SECTIONS
   .text ${RELOCATING+ __image_base__ + ( __section_alignment__ < ${TARGET_PAGE_SIZE} ? . : __section_alignment__ )} :
   {
     ${RELOCATING+KEEP (*(SORT_NONE(.init)))}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${R_TEXT}
     ${RELOCATING+ *(.text.*)}
@@ -154,6 +155,7 @@ SECTIONS
   .data ${RELOCATING+BLOCK(__section_alignment__)} :
   {
     ${RELOCATING+__data_start__ = . ;}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data)
     ${RELOCATING+*(.data2)}
     ${R_DATA}
diff --git a/ld/scripttempl/pru.sc b/ld/scripttempl/pru.sc
index 3ff86bc61c7..bf2b7479d46 100644
--- a/ld/scripttempl/pru.sc
+++ b/ld/scripttempl/pru.sc
@@ -110,6 +110,7 @@ SECTIONS
     ${RELOCATING+KEEP (*(.init0))}
 
     ${RELOCATING+. = ALIGN(4);}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+. = ALIGN(4);}
     ${RELOCATING+*(.text.*)}
@@ -145,6 +146,7 @@ SECTIONS
     . += (. == 0 ? 4 : 0);}
 
     ${RELOCATING+ PROVIDE (_data_start = .) ; }
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data)
     ${RELOCATING+ *(.data*)}
     ${RELOCATING+ *(.data:*)}
diff --git a/ld/scripttempl/v850.sc b/ld/scripttempl/v850.sc
index 10d1da8b5bb..b59b194be2f 100644
--- a/ld/scripttempl/v850.sc
+++ b/ld/scripttempl/v850.sc
@@ -76,6 +76,7 @@ SECTIONS
 
   .text		:
   {
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+*(.text.*)}
 
@@ -108,6 +109,7 @@ SECTIONS
 
   .data		:
   {
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data)
     ${RELOCATING+*(.data.*)
     *(.gnu.linkonce.d*)}
diff --git a/ld/scripttempl/v850_rh850.sc b/ld/scripttempl/v850_rh850.sc
index e63e7db8884..78d99e25366 100644
--- a/ld/scripttempl/v850_rh850.sc
+++ b/ld/scripttempl/v850_rh850.sc
@@ -80,6 +80,7 @@ SECTIONS
 
   .text		:
   {
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+*(.text.*)}
 
@@ -118,6 +119,7 @@ SECTIONS
 
   .data		:
   {
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data)
     ${RELOCATING+*(.data.*)
     *(.gnu.linkonce.d*)}
diff --git a/ld/scripttempl/visium.sc b/ld/scripttempl/visium.sc
index 0b90b888136..9038372499c 100644
--- a/ld/scripttempl/visium.sc
+++ b/ld/scripttempl/visium.sc
@@ -67,6 +67,7 @@ SECTIONS
 
   .text ${RELOCATING-0} : {
     ${RELOCATING+ _ftext  =  .;}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+*(.text.*)}
     ${RELOCATING+*(.gnu.linkonce.t.*)}
@@ -131,6 +132,7 @@ SECTIONS
   .data ${RELOCATING-0} : {
     ${RELOCATING+ . = ALIGN(4);}
     ${RELOCATING+ _sdata  =  .;}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data)
     ${RELOCATING+*(.data.*)}
     ${RELOCATING+*(.gnu.linkonce.d.*)}
diff --git a/ld/scripttempl/xstormy16.sc b/ld/scripttempl/xstormy16.sc
index c4117fcde3e..4e180730afe 100644
--- a/ld/scripttempl/xstormy16.sc
+++ b/ld/scripttempl/xstormy16.sc
@@ -133,6 +133,7 @@ SECTIONS
     ${RELOCATING+__rdata = .;}
     ${RELOCATING+__data = .;}
     ${RELOCATING+${DATA_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.data)
     ${RELOCATING+*(.data.*)}
     ${RELOCATING+*(.gnu.linkonce.d.*)}
@@ -179,6 +180,7 @@ SECTIONS
   .text    ${RELOCATING-0} :
   {
     ${RELOCATING+${TEXT_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE section_ordering_file}
     *(.text)
     ${RELOCATING+*(.text.*)}
     *(.stub)
--- /dev/null	2024-04-25 08:33:45.365694295 +0100
+++ current/ld/testsuite/ld-scripts/start.s	2024-04-24 14:27:08.712528579 +0100
@@ -0,0 +1,14 @@
+	.text
+	.global start	/* Used by SH targets.  */
+start:
+	.global _start
+_start:
+	.global __start
+__start:
+	.global _mainCRTStartup	/* Used by PE targets.  */
+_mainCRTStartup:
+	.global main	/* Used by HPPA targets.  */
+main:
+	.globl	_main	/* Used by LynxOS targets.  */
+_main:
+	.dc.a 0
--- /dev/null	2024-04-25 08:33:45.365694295 +0100
+++ current/ld/testsuite/ld-scripts/section-order-1a.d	2024-04-25 13:03:15.167491733 +0100
@@ -0,0 +1,17 @@
+#source: section-order-1b.s
+#source: section-order-1a.s
+#source: start.s
+#ld: --section-ordering-file section-order-1a.t
+#nm: -n
+
+#...
+[0-9a-f]+ T yyy
+#...
+[0-9a-f]+ T bar
+#...
+[0-9a-f]+ T [_]+start
+#...
+[0-9a-f]+ T xxx
+#...
+[0-9a-f]+ T foo
+#pass
--- /dev/null	2024-04-25 08:33:45.365694295 +0100
+++ current/ld/testsuite/ld-scripts/section-order-1a.s	2024-04-25 13:00:05.240474764 +0100
@@ -0,0 +1,19 @@
+	.section .text.foo
+	.globl	foo
+foo:
+	.dc.a 0
+	
+	.section .text.bar
+	.globl	bar
+bar:
+	.dc.a 0
+
+	.section .data.small
+	.globl small
+small:
+	.dc.a 0
+
+	.section .bar
+	.global bar
+bart:
+	.dc.a 0
--- /dev/null	2024-04-25 08:33:45.365694295 +0100
+++ current/ld/testsuite/ld-scripts/section-order-1a.t	2024-04-25 12:59:23.432471029 +0100
@@ -0,0 +1,20 @@
+.text.yyy
+
+# Multiple section-regexps can be separated by spaces
+.text.b?r .text
+
+# Inputs for different outputs can appear in a mixed order in the file.
+.data.small
+
+# Tabs count as separfators too.
+.text.xxx	.text.foo
+
+# Input sections whose names do not match the output section can be included by putting the output section name first.
+.data(.big*)
+
+# Multiple input sections can also be specified in this way.
+# Ordering of sections within the parenthesised list is not guaranteed.
+.data(.bar .baz*)
+
+# The linker will not warn if an entry is not used.
+.foo.bar
--- /dev/null	2024-04-25 08:33:45.365694295 +0100
+++ current/ld/testsuite/ld-scripts/section-order-1b.d	2024-04-25 13:03:36.592493646 +0100
@@ -0,0 +1,17 @@
+#source: section-order-1a.s
+#source: section-order-1b.s
+#source: start.s
+#ld: --section-ordering-file section-order-1b.t
+#nm: -n
+
+#...
+[0-9a-f]+ T yyy
+#...
+[0-9a-f]+ T bar
+#...
+[0-9a-f]+ T [_]+start
+#...
+[0-9a-f]+ T xxx
+#...
+[0-9a-f]+ T foo
+#pass
--- /dev/null	2024-04-25 08:33:45.365694295 +0100
+++ current/ld/testsuite/ld-scripts/section-order-1b.s	2024-04-25 12:59:47.416473174 +0100
@@ -0,0 +1,19 @@
+	.section .text.xxx
+	.globl	xxx
+xxx:
+	.dc.a 0
+	
+	.section .text.yyy
+	.globl	yyy
+yyy:
+	.dc.a 0
+
+	.section .big
+	.global big
+big:
+	.dc.a 0
+
+	.section .baz
+	.global baz
+baz:
+	.dc.a 0
--- /dev/null	2024-04-25 08:33:45.365694295 +0100
+++ current/ld/testsuite/ld-scripts/section-order-1b.t	2024-04-25 12:55:08.604453855 +0100
@@ -0,0 +1,4 @@
+.text.yyy
+.text.b?r
+.text(*t)
+.text.xxx .text.foo
--- /dev/null	2024-04-25 08:33:45.365694295 +0100
+++ current/ld/testsuite/ld-scripts/section-order-1c.d	2024-04-25 13:04:12.080496817 +0100
@@ -0,0 +1,6 @@
+#source: section-order-1a.s
+#source: section-order-1b.s
+#source: start.s
+#ld: --section-ordering-file section-order-1c.t
+#nm: -n
+#error: .*: 'INCLUDE section-order-1b.t' found in the section ordering file: 'section-order-1c.t'
--- /dev/null	2024-04-25 08:33:45.365694295 +0100
+++ current/ld/testsuite/ld-scripts/section-order-1c.t	2024-04-25 13:07:15.671497250 +0100
@@ -0,0 +1,5 @@
+.text.yyy
+.text.b?r
+INCLUDE section-order-1b.t
+.t*t
+.text.xxx .text.foo
--- /dev/null	2024-04-25 08:33:45.365694295 +0100
+++ current/ld/testsuite/ld-scripts/section-order-1d.d	2024-04-25 13:05:43.864501411 +0100
@@ -0,0 +1,13 @@
+#source: section-order-1b.s
+#source: section-order-1a.s
+#source: start.s
+#ld: --section-ordering-file section-order-1a.t
+#nm: -n
+
+#...
+[0-9a-f]+ D small
+#...
+[0-9a-f]+ D big
+#...
+[0-9a-f]+ D ba.*
+#pass
--- /dev/null	2024-04-25 08:33:45.365694295 +0100
+++ current/ld/testsuite/ld-scripts/section-order.exp	2024-04-25 13:02:50.591489535 +0100
@@ -0,0 +1,45 @@
+# Test for --section-ordering-file FILE.
+# Copyright (C) 2024 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# 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 --section-ordering-file option is only supported by ELF and
+# PE COFF linkers, which allow for arbitrarily named sections, eg:
+# .text.*
+if { !([is_elf_format] || [is_pecoff_format]) } {
+    return
+}
+
+set old_ldflags $LDFLAGS
+if { [istarget spu*-*-*] } then {
+    set LDFLAGS "$LDFLAGS --local-store 0:0 --no-overlays"
+} elseif { [is_pecoff_format] } then {
+    set LDFLAGS "$LDFLAGS --image-base 0"
+} elseif { [is_xcoff_format] } then {
+    set LDFLAGS "$LDFLAGS -bnogc"
+}
+
+set test_list [lsort [glob -nocomplain $srcdir/$subdir/section-order*.d]]
+foreach test_file $test_list {
+    set test_name [file rootname $test_file]
+    set map_file "tmpdir/[file tail $test_name].map"
+    verbose $test_name
+    run_dump_test $test_name
+}
+
+set LDFLAGS $old_ldflags

             reply	other threads:[~2024-04-25 13:01 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-25 13:01 Nick Clifton [this message]
2024-04-25 15:32 ` H.J. Lu
2024-04-26  9:38   ` Nick Clifton
2024-04-26  1:46 ` Hans-Peter Nilsson
2024-04-26  9:46   ` Nick Clifton
2024-04-27  0:46     ` Hans-Peter Nilsson
2024-04-26  4:17 ` Alan Modra
2024-04-26  9:59   ` Nick Clifton
2024-04-26 12:43     ` Alan Modra
2024-04-29  0:12       ` Alan Modra
2024-05-02 15:16         ` Nick Clifton
2024-05-06 18:27         ` H.J. Lu
2024-05-10 21:46           ` Noah Goldstein
2024-05-11 13:01             ` H.J. Lu
2024-05-07 16:39         ` RFC: ld: Add --text-section-ordering-file (version 4) Nick Clifton
2024-05-10 12:25           ` Alan Modra
2024-05-10 16:00             ` Nick Clifton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87edat7g1e.fsf@redhat.com \
    --to=nickc@redhat.com \
    --cc=binutils@sourceware.org \
    --cc=hjl.tools@gmail.com \
    --cc=siddhesh@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).