public inbox for binutils-cvs@sourceware.org
 help / color / mirror / Atom feed
* [binutils-gdb] Add --section-ordering command line option to the bfd linker.
@ 2024-05-10 15:59 Nick Clifton
  0 siblings, 0 replies; only message in thread
From: Nick Clifton @ 2024-05-10 15:59 UTC (permalink / raw)
  To: binutils-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6e8376fa569e62379a42b91b0afd1f4086f1d897

commit 6e8376fa569e62379a42b91b0afd1f4086f1d897
Author: Nick Clifton <nickc@redhat.com>
Date:   Fri May 10 16:59:05 2024 +0100

    Add --section-ordering command line option to the bfd linker.

Diff:
---
 ld/NEWS                                    |  3 ++
 ld/ld.h                                    |  4 ++
 ld/ld.texi                                 | 72 +++++++++++++++++++++++---
 ld/ldfile.c                                | 15 +-----
 ld/ldfile.h                                | 19 ++++++-
 ld/ldgram.y                                | 36 ++++++++++++-
 ld/ldlang.c                                | 81 +++++++++++++++++++++---------
 ld/ldlang.h                                |  5 ++
 ld/ldlex.h                                 |  2 +
 ld/ldlex.l                                 | 11 ++--
 ld/ldmain.c                                | 55 ++++++++++++++------
 ld/lexsup.c                                |  9 ++++
 ld/testsuite/ld-scripts/section-order-1a.d | 22 ++++++++
 ld/testsuite/ld-scripts/section-order-1a.s | 29 +++++++++++
 ld/testsuite/ld-scripts/section-order-1a.t | 14 ++++++
 ld/testsuite/ld-scripts/section-order-1b.d | 18 +++++++
 ld/testsuite/ld-scripts/section-order-1b.s | 34 +++++++++++++
 ld/testsuite/ld-scripts/section-order-1b.t |  7 +++
 ld/testsuite/ld-scripts/section-order-1c.d | 14 ++++++
 ld/testsuite/ld-scripts/section-order-1d.d | 18 +++++++
 ld/testsuite/ld-scripts/section-order.exp  | 45 +++++++++++++++++
 ld/testsuite/ld-scripts/start.s            | 14 ++++++
 22 files changed, 462 insertions(+), 65 deletions(-)

diff --git a/ld/NEWS b/ld/NEWS
index f70d2157339..00eb46047d1 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* Add --section-ordering-file <FILE> option to add extra mapping of input
+  sections to output sections.
+
 * Add -plugin-save-temps to store plugin intermediate files permanently.
 
 Changes in 2.42:
diff --git a/ld/ld.h b/ld/ld.h
index fcdd9a2c083..0dee944cf2a 100644
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -196,6 +196,9 @@ typedef struct
 
   /* Default linker script.  */
   char *default_script;
+
+  /* Linker script fragment provided by the --section-order command line option.  */
+  char *section_ordering_file;
 } args_type;
 
 extern args_type command_line;
@@ -325,6 +328,7 @@ extern ld_config_type config;
 
 extern FILE * saved_script_handle;
 extern bool force_make_executable;
+extern bool in_section_ordering;
 
 extern int yyparse (void);
 extern void add_cref (const char *, bfd *, asection *, bfd_vma);
diff --git a/ld/ld.texi b/ld/ld.texi
index ca9574dfc71..b32bb463f3f 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -302,6 +302,7 @@ and the script command language.  If @emph{no} binary input files at all
 are specified, the linker does not produce any output, and issues the
 message @samp{No input files}.
 
+@anchor{unrecognised-input-files}
 If the linker cannot recognize the format of an object file, it will
 assume that it is a linker script.  A script specified in this way
 augments the main linker script used for the link (either the default
@@ -1163,18 +1164,32 @@ a linker bug report.
 @itemx --script=@var{scriptfile}
 Use @var{scriptfile} as the linker script.  This script replaces
 @command{ld}'s default linker script (rather than adding to it),
-unless the script contains @code{INSERT}, so
-@var{commandfile} must specify everything necessary to describe the
-output file.  @xref{Scripts}.  If @var{scriptfile} does not exist in
-the current directory, @code{ld} looks for it in the directories
-specified by any preceding @samp{-L} options.  Multiple @samp{-T}
-options accumulate.
+unless the script contains @code{INSERT}, so @var{commandfile} must
+specify everything necessary to describe the output file.
+@xref{Scripts}.
+
+If @var{scriptfile} does not exist in the current directory, @code{ld}
+looks for it in the directories specified by any preceding @samp{-L}
+options.
+
+Command line options that appear before the @option{-T} option can
+affect the script, but command line options that appear after it do
+not.
+
+Multiple @samp{-T} options will accumulate if they are augmenting the
+current script, otherwise the last, non-augmenting, @option{-T} option
+will be used.
+
+There are other ways of specifying linker scripts.  See
+@xref{--default-script}, @xref{--section-ordering-file} and
+@xref{unrecognised-input-files}.
 
 @kindex -dT @var{script}
 @kindex --default-script=@var{script}
 @cindex script files
 @item -dT @var{scriptfile}
 @itemx --default-script=@var{scriptfile}
+@anchor{--default-script}
 Use @var{scriptfile} as the default linker script.  @xref{Scripts}.
 
 This option is similar to the @option{--script} option except that
@@ -2521,6 +2536,51 @@ warning and continue with the link.
 
 @end ifset
 
+@kindex --section-ordering-file
+@item --section-ordering-file=@var{script}
+@anchor{--section-ordering-file}
+This option is used to augment the current linker script with
+additional mapping of input sections to output sections.  This file
+must use the same syntax for @code{SECTIONS} as is used in normal
+linker scripts, but it should not do anything other than place input
+sections into output sections. @pxref{SECTIONS}
+
+A second constraint on the section ordering script is that it can only
+reference output sections that are already defined by whichever linker
+script is currently in use.  (Ie the default linker script or a script
+specified on the command line).  The benefit of the section ordering
+script however is that the input sections are mapped to the start of
+the output sections, so that they can ensure the ordering of sections
+in the output section.  For example, imagine that the default linker
+script looks like this:
+
+@smallexample
+SECTIONS @{
+  .text : @{ *(.text.hot) ; *(.text .text.*) @}
+  .data : @{ *(.data.big) ; *(.data .data.*) @}
+  @}
+@end smallexample
+
+Then if a section ordering file like this is used:
+
+@smallexample
+  .text : @{ *(.text.first) ; *(.text.z*) @}
+  .data : @{ foo.o(.data.first) ; *(.data.small) @}
+@end smallexample
+
+This would be equivalent to a linker script like this:
+
+@smallexample
+SECTIONS @{
+  .text : @{ *(.text.first) ; *(.text.z*) ; *(.text.hot) ; *(.text .text.*) @}
+  .data : @{ foo.o(.data.first) ; *(.data.small) ; *(.data.big) ; *(.data .data.*) @}
+  @}
+@end smallexample
+
+The advantage of the section ordering file is that it can be used to
+order those sections that matter to the user without having to worry
+about any other sections, or memory regions, or anything else.
+
 @kindex -shared
 @kindex -Bshareable
 @item -shared
diff --git a/ld/ldfile.c b/ld/ldfile.c
index dc9875d8813..f1107a1b7d7 100644
--- a/ld/ldfile.c
+++ b/ld/ldfile.c
@@ -871,19 +871,7 @@ ldfile_find_command_file (const char *name,
   return result;
 }
 
-enum script_open_style {
-  script_nonT,
-  script_T,
-  script_defaultT
-};
-
-struct script_name_list
-{
-  struct script_name_list *next;
-  enum script_open_style open_how;
-  char name[1];
-};
-
+struct script_name_list *processed_scripts = NULL;
 /* Open command file NAME.  */
 
 static void
@@ -891,7 +879,6 @@ ldfile_open_command_file_1 (const char *name, enum script_open_style open_how)
 {
   FILE *ldlex_input_stack;
   bool sysrooted;
-  static struct script_name_list *processed_scripts = NULL;
   struct script_name_list *script;
   size_t len;
 
diff --git a/ld/ldfile.h b/ld/ldfile.h
index f17677e9e9a..f79abf2310d 100644
--- a/ld/ldfile.h
+++ b/ld/ldfile.h
@@ -29,7 +29,8 @@ extern const char *ldfile_output_machine_name;
 /* Structure used to hold the list of directories to search for
    libraries.  */
 
-typedef struct search_dirs {
+typedef struct search_dirs
+{
   /* Next directory on list.  */
   struct search_dirs *next;
   /* Name of directory.  */
@@ -38,6 +39,22 @@ typedef struct search_dirs {
   bool cmdline;
 } search_dirs_type;
 
+enum script_open_style
+{
+  script_nonT,
+  script_T,
+  script_defaultT
+};
+
+struct script_name_list
+{
+  struct script_name_list *  next;
+  enum script_open_style     open_how;
+  char                       name[1];
+};
+
+extern struct script_name_list * processed_scripts;
+
 extern search_dirs_type *search_head;
 
 extern void ldfile_add_arch
diff --git a/ld/ldgram.y b/ld/ldgram.y
index 0d531fddfa1..07c19ba8692 100644
--- a/ld/ldgram.y
+++ b/ld/ldgram.y
@@ -157,7 +157,7 @@ static void yyerror (const char *);
 %token LOG2CEIL FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
 %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
 %token <name> VERS_TAG VERS_IDENTIFIER
-%token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT
+%token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT INPUT_SECTION_ORDERING_SCRIPT
 %token KEEP ONLY_IF_RO ONLY_IF_RW SPECIAL INPUT_SECTION_FLAGS ALIGN_WITH_INPUT
 %token EXCLUDE_FILE
 %token CONSTANT
@@ -172,6 +172,7 @@ file:
 		INPUT_SCRIPT script_file
 	|	INPUT_MRI_SCRIPT mri_script_file
 	|	INPUT_VERSION_SCRIPT version_script_file
+	|	INPUT_SECTION_ORDERING_SCRIPT section_ordering_script_file
 	|	INPUT_DYNAMIC_LIST dynamic_list_file
 	|	INPUT_DEFSYM defsym_expr
 	;
@@ -1539,6 +1540,39 @@ opt_semicolon:
 	|	';'
 	;
 
+section_ordering_script_file:
+		{
+		  ldlex_script ();
+		  PUSH_ERROR (_("section-ordering-file script"));
+		}
+		section_ordering_list
+		{
+		  ldlex_popstate ();
+		  POP_ERROR ();
+		}
+	;
+
+section_ordering_list:
+		section_ordering_list section_order
+	|	section_ordering_list statement_anywhere
+	|
+	;
+
+section_order:	NAME ':'
+		{
+		  ldlex_wild ();
+		  lang_enter_output_section_statement
+		    ($1, NULL, 0, NULL, NULL, NULL, NULL, 0, 0);
+		}
+		'{'
+		statement_list_opt
+		'}'
+		{
+		  ldlex_popstate ();
+		  lang_leave_output_section_statement (NULL, NULL, NULL, NULL);
+		}
+		opt_comma
+
 %%
 static void
 yyerror (const char *arg)
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 54d1af62ebe..9e8cc224f4d 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -1299,6 +1299,7 @@ output_section_statement_newfunc (struct bfd_hash_entry *entry,
   ret->s.output_section_statement.section_alignment = NULL;
   ret->s.output_section_statement.block_value = 1;
   lang_list_init (&ret->s.output_section_statement.children);
+  lang_list_init (&ret->s.output_section_statement.sort_children);
   lang_statement_append (stat_ptr, &ret->s, &ret->s.header.next);
 
   /* For every output section statement added to the list, except the
@@ -7613,13 +7614,22 @@ lang_enter_output_section_statement (const char *output_section_statement_name,
   lang_output_section_statement_type *os;
 
   os = lang_output_section_statement_lookup (output_section_statement_name,
-					     constraint, 2);
+					     constraint,
+					     in_section_ordering ? 0 : 2);
+  if (os == NULL) /* && in_section_ordering */
+    einfo (_("%F%P:%pS: error: output section '%s' must already exist\n"),
+	   NULL, output_section_statement_name);
   current_section = os;
 
+  /* Make next things chain into subchain of this.  */
+  push_stat_ptr (in_section_ordering ? &os->sort_children : &os->children);
+
+  if (in_section_ordering)
+    return os;
+
   if (os->addr_tree == NULL)
-    {
-      os->addr_tree = address_exp;
-    }
+    os->addr_tree = address_exp;
+
   os->sectype = sectype;
   if (sectype == type_section || sectype == typed_readonly_section)
     os->sectype_value = sectype_value;
@@ -7629,9 +7639,6 @@ lang_enter_output_section_statement (const char *output_section_statement_name,
     os->flags = SEC_NO_FLAGS;
   os->block_value = 1;
 
-  /* Make next things chain into subchain of this.  */
-  push_stat_ptr (&os->children);
-
   os->align_lma_with_input = align_with_input == ALIGN_WITH_INPUT;
   if (os->align_lma_with_input && align != NULL)
     einfo (_("%F%P:%pS: error: align with input and explicit align specified\n"),
@@ -7971,21 +7978,6 @@ find_rescan_insertion (lang_input_statement_type *add)
   return iter;
 }
 
-/* Insert SRCLIST into DESTLIST after given element by chaining
-   on FIELD as the next-pointer.  (Counterintuitively does not need
-   a pointer to the actual after-node itself, just its chain field.)  */
-
-static void
-lang_list_insert_after (lang_statement_list_type *destlist,
-			lang_statement_list_type *srclist,
-			lang_statement_union_type **field)
-{
-  *(srclist->tail) = *field;
-  *field = srclist->head;
-  if (destlist->tail == field)
-    destlist->tail = srclist->tail;
-}
-
 /* Detach new nodes added to DESTLIST since the time ORIGLIST
    was taken as a copy of it and leave them in ORIGLIST.  */
 
@@ -8033,6 +8025,21 @@ find_next_input_statement (lang_statement_union_type **s)
 }
 #endif /* BFD_SUPPORTS_PLUGINS */
 
+/* Insert SRCLIST into DESTLIST after given element by chaining
+   on FIELD as the next-pointer.  (Counterintuitively does not need
+   a pointer to the actual after-node itself, just its chain field.)  */
+
+static void
+lang_list_insert_after (lang_statement_list_type *destlist,
+			lang_statement_list_type *srclist,
+			lang_statement_union_type **field)
+{
+  *(srclist->tail) = *field;
+  *field = srclist->head;
+  if (destlist->tail == field)
+    destlist->tail = srclist->tail;
+}
+
 /* Add NAME to the list of garbage collection entry points.  */
 
 void
@@ -8127,9 +8134,34 @@ reset_resolved_wilds (void)
   lang_for_each_statement (reset_one_wild);
 }
 
+/* For each output section statement, splice any entries on the
+   sort_children list before the first wild statement on the children
+   list.  */
+
+static void
+lang_os_merge_sort_children (void)
+{
+  lang_output_section_statement_type *os;
+  for (os = (void *) lang_os_list.head; os != NULL; os = os->next)
+    {
+      if (os->sort_children.head != NULL)
+	{
+	  lang_statement_union_type **where;
+	  for (where = &os->children.head;
+	       *where != NULL;
+	       where = &(*where)->header.next)
+	    if ((*where)->header.type == lang_wild_statement_enum)
+	      break;
+	  lang_list_insert_after (&os->children, &os->sort_children, where);
+	}
+    }
+}
+
 void
 lang_process (void)
 {
+  lang_os_merge_sort_children ();
+
   /* Finalize dynamic list.  */
   if (link_info.dynamic_list)
     lang_finalize_version_expr_head (&link_info.dynamic_list->head);
@@ -8817,6 +8849,10 @@ lang_leave_output_section_statement (fill_type *fill, const char *memspec,
 				     lang_output_section_phdr_list *phdrs,
 				     const char *lma_memspec)
 {
+  pop_stat_ptr ();
+  if (in_section_ordering)
+    return;
+
   lang_get_regions (&current_section->region,
 		    &current_section->lma_region,
 		    memspec, lma_memspec,
@@ -8825,7 +8861,6 @@ lang_leave_output_section_statement (fill_type *fill, const char *memspec,
 
   current_section->fill = fill;
   current_section->phdrs = phdrs;
-  pop_stat_ptr ();
 }
 
 /* Set the output format type.  -oformat overrides scripts.  */
diff --git a/ld/ldlang.h b/ld/ldlang.h
index ea1c26d00f3..4c1bb002f8e 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -141,7 +141,12 @@ typedef struct lang_output_section_phdr_list
 typedef struct lang_output_section_statement_struct
 {
   lang_statement_header_type header;
+  /* Input sections to be mapped to this output section.  */
   lang_statement_list_type children;
+  /* Input sections to be mapped to the start of this output section.
+     These sections are provided by the --section-ordering file, if used.  */
+  lang_statement_list_type sort_children;
+
   struct lang_output_section_statement_struct *next;
   struct lang_output_section_statement_struct *prev;
   const char *name;
diff --git a/ld/ldlex.h b/ld/ldlex.h
index d575562a357..7a0c3b4be94 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -62,6 +62,7 @@ enum option_values
   OPTION_SONAME,
   OPTION_SORT_COMMON,
   OPTION_SORT_SECTION,
+  OPTION_SECTION_ORDERING_FILE,
   OPTION_STATS,
   OPTION_SYMBOLIC,
   OPTION_SYMBOLIC_FUNCTIONS,
@@ -477,6 +478,7 @@ typedef enum input_enum
   input_script,
   input_mri_script,
   input_version_script,
+  input_section_ordering_script,
   input_dynamic_list,
   input_defsym
 } input_type;
diff --git a/ld/ldlex.l b/ld/ldlex.l
index e113c90812b..aa613100db0 100644
--- a/ld/ldlex.l
+++ b/ld/ldlex.l
@@ -120,11 +120,12 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
       parser_input = input_selected;
       switch (t)
 	{
-	case input_script: return INPUT_SCRIPT; break;
-	case input_mri_script: return INPUT_MRI_SCRIPT; break;
-	case input_version_script: return INPUT_VERSION_SCRIPT; break;
-	case input_dynamic_list: return INPUT_DYNAMIC_LIST; break;
-	case input_defsym: return INPUT_DEFSYM; break;
+	case input_script: return INPUT_SCRIPT;
+	case input_mri_script: return INPUT_MRI_SCRIPT;
+	case input_version_script: return INPUT_VERSION_SCRIPT;
+	case input_section_ordering_script: return INPUT_SECTION_ORDERING_SCRIPT;
+	case input_dynamic_list: return INPUT_DYNAMIC_LIST;
+	case input_defsym: return INPUT_DEFSYM;
 	default: abort ();
 	}
     }
diff --git a/ld/ldmain.c b/ld/ldmain.c
index fe389681bd3..037099b9d37 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -90,6 +90,8 @@ bool version_printed;
 /* TRUE if we should demangle symbol names.  */
 bool demangling;
 
+bool in_section_ordering;
+
 args_type command_line;
 
 ld_config_type config;
@@ -246,6 +248,26 @@ ld_bfd_error_handler (const char *fmt, va_list ap)
   (*default_bfd_error_handler) (fmt, ap);
 }
 
+static void
+display_external_script (void)
+{
+  if (saved_script_handle == NULL)
+    return;
+  
+  static const int ld_bufsz = 8193;
+  size_t n;
+  char *buf = (char *) xmalloc (ld_bufsz);
+
+  rewind (saved_script_handle);
+  while ((n = fread (buf, 1, ld_bufsz - 1, saved_script_handle)) > 0)
+    {
+      buf[n] = 0;
+      info_msg ("%s", buf);
+    }
+  rewind (saved_script_handle);
+  free (buf);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -416,26 +438,13 @@ main (int argc, char **argv)
   if (verbose)
     {
       if (saved_script_handle)
-	info_msg (_("using external linker script:"));
+	info_msg (_("using external linker script: %s"), processed_scripts->name);
       else
 	info_msg (_("using internal linker script:"));
       info_msg ("\n==================================================\n");
 
       if (saved_script_handle)
-	{
-	  static const int ld_bufsz = 8193;
-	  size_t n;
-	  char *buf = (char *) xmalloc (ld_bufsz);
-
-	  rewind (saved_script_handle);
-	  while ((n = fread (buf, 1, ld_bufsz - 1, saved_script_handle)) > 0)
-	    {
-	      buf[n] = 0;
-	      info_msg ("%s", buf);
-	    }
-	  rewind (saved_script_handle);
-	  free (buf);
-	}
+	display_external_script ();
       else
 	{
 	  int isfile;
@@ -446,6 +455,22 @@ main (int argc, char **argv)
       info_msg ("\n==================================================\n");
     }
 
+  if (command_line.section_ordering_file)
+    {
+      FILE *hold_script_handle;
+
+      hold_script_handle = saved_script_handle;
+      ldfile_open_command_file (command_line.section_ordering_file);
+      if (verbose)
+	display_external_script ();
+      saved_script_handle = hold_script_handle;
+      in_section_ordering = true;
+      parser_input = input_section_ordering_script;
+      yyparse ();
+      in_section_ordering = false;
+
+    }
+
   if (command_line.force_group_allocation
       || !bfd_link_relocatable (&link_info))
     link_info.resolve_section_groups = true;
diff --git a/ld/lexsup.c b/ld/lexsup.c
index dad3b6059ed..4125d849f2c 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 },
@@ -1400,6 +1403,12 @@ parse_args (unsigned argc, char **argv)
 	    einfo (_("%F%P: invalid section sorting option: %s\n"),
 		   optarg);
 	  break;
+	case OPTION_SECTION_ORDERING_FILE:
+	  if (command_line.section_ordering_file != NULL
+	      && strcmp (optarg, command_line.section_ordering_file) != 0)
+	    einfo (_("%P: warning: section ordering file changed.  Ignoring earlier definition\n"));
+	  command_line.section_ordering_file = optarg;
+	  break;
 	case OPTION_STATS:
 	  config.stats = true;
 	  break;
diff --git a/ld/testsuite/ld-scripts/section-order-1a.d b/ld/testsuite/ld-scripts/section-order-1a.d
new file mode 100644
index 00000000000..40730b82a8d
--- /dev/null
+++ b/ld/testsuite/ld-scripts/section-order-1a.d
@@ -0,0 +1,22 @@
+#name: Text Section Ordering (section-order-1a)
+#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
+#...
+[0-9a-f]+ T qqq
+#...
+[0-9a-f]+ T zzz
+#pass
diff --git a/ld/testsuite/ld-scripts/section-order-1a.s b/ld/testsuite/ld-scripts/section-order-1a.s
new file mode 100644
index 00000000000..2394a7ba902
--- /dev/null
+++ b/ld/testsuite/ld-scripts/section-order-1a.s
@@ -0,0 +1,29 @@
+	.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
+
+	.section .text.zzz
+	.global zzz
+zzz:
+	.dc.a 0
+
+	.section .data.bbb
+	.global bbb
+bbb:
+	.dc.a 0
diff --git a/ld/testsuite/ld-scripts/section-order-1a.t b/ld/testsuite/ld-scripts/section-order-1a.t
new file mode 100644
index 00000000000..2e28bfa8451
--- /dev/null
+++ b/ld/testsuite/ld-scripts/section-order-1a.t
@@ -0,0 +1,14 @@
+.text : {
+    *(.text.yyy)
+    *(.text.b?r)
+    *(.text)
+    *(.text.xxx .text.foo)
+}
+
+.data : {
+    *(.data.small)
+    *(.big*)
+    *(.bar .baz*)
+    *(.data.ccc)
+}
+
diff --git a/ld/testsuite/ld-scripts/section-order-1b.d b/ld/testsuite/ld-scripts/section-order-1b.d
new file mode 100644
index 00000000000..caf713dd915
--- /dev/null
+++ b/ld/testsuite/ld-scripts/section-order-1b.d
@@ -0,0 +1,18 @@
+#name: Text Section Ordering (section-order-1b)
+#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
diff --git a/ld/testsuite/ld-scripts/section-order-1b.s b/ld/testsuite/ld-scripts/section-order-1b.s
new file mode 100644
index 00000000000..49a0b32475a
--- /dev/null
+++ b/ld/testsuite/ld-scripts/section-order-1b.s
@@ -0,0 +1,34 @@
+	.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
+
+	.section .text.qqq
+	.global qqq
+qqq:
+	.dc.a 0
+
+	.section .data.ccc
+	.global ccc
+ccc:
+	.dc.a 0
+
+	.data
+	.global data_symbol
+data_symbol:
+	.dc.a 0
diff --git a/ld/testsuite/ld-scripts/section-order-1b.t b/ld/testsuite/ld-scripts/section-order-1b.t
new file mode 100644
index 00000000000..6a36250dcbc
--- /dev/null
+++ b/ld/testsuite/ld-scripts/section-order-1b.t
@@ -0,0 +1,7 @@
+.text : {
+  *(.text.yyy)
+  *(.text.b?r)
+  *(*t)
+  *(.text.xxx)
+  *(.text.foo)
+}
diff --git a/ld/testsuite/ld-scripts/section-order-1c.d b/ld/testsuite/ld-scripts/section-order-1c.d
new file mode 100644
index 00000000000..ad06d4ac0d4
--- /dev/null
+++ b/ld/testsuite/ld-scripts/section-order-1c.d
@@ -0,0 +1,14 @@
+#name: Data Section Ordering (section-order-1c)
+#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
diff --git a/ld/testsuite/ld-scripts/section-order-1d.d b/ld/testsuite/ld-scripts/section-order-1d.d
new file mode 100644
index 00000000000..d0165056e66
--- /dev/null
+++ b/ld/testsuite/ld-scripts/section-order-1d.d
@@ -0,0 +1,18 @@
+#name: Data Section Ordering (section-order-1d)
+#source: section-order-1a.s
+#source: section-order-1b.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 bart
+#...
+[0-9a-f]+ D ccc
+#...
+[0-9a-f]+ D bbb
+#pass
diff --git a/ld/testsuite/ld-scripts/section-order.exp b/ld/testsuite/ld-scripts/section-order.exp
new file mode 100644
index 00000000000..9b87e746cd1
--- /dev/null
+++ b/ld/testsuite/ld-scripts/section-order.exp
@@ -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
diff --git a/ld/testsuite/ld-scripts/start.s b/ld/testsuite/ld-scripts/start.s
new file mode 100644
index 00000000000..3f646267716
--- /dev/null
+++ b/ld/testsuite/ld-scripts/start.s
@@ -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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-05-10 15:59 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-10 15:59 [binutils-gdb] Add --section-ordering command line option to the bfd linker Nick Clifton

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).