RFC: ld: Add --section-ordering-file FILE

H.J. Lu hongjiu.lu@intel.com
Mon Apr 15 22:48:00 GMT 2019


Does this sound a good idea?


H.J.
---
[hjl@gnu-cfl-1 order-1]$ cat x.c
extern void foo (void);
extern void bar (void);

void
xxx (void)
{
  foo ();
  bar ();
}
[hjl@gnu-cfl-1 order-1]$ cat foo.c
void
foo (void)
{
}
[hjl@gnu-cfl-1 order-1]$ cat bar.c
void
bar (void)
{
}
[hjl@gnu-cfl-1 order-1]$ cat section-order
*(.text.bar)
*(.text.xxx)
*(.text.foo)
[hjl@gnu-cfl-1 order-1]$ make
gcc -B./ -fPIC -fdata-sections -ffunction-sections   -c -o x.o x.c
gcc -B./ -fPIC -fdata-sections -ffunction-sections   -c -o foo.o foo.c
gcc -B./ -fPIC -fdata-sections -ffunction-sections   -c -o bar.o bar.c
./ld -shared -L. --section-ordering-file section-order -o x.so x.o foo.o bar.o
nm -n x.so
0000000000001030 T bar
0000000000001037 T xxx
0000000000001048 T foo
0000000000003f00 d _DYNAMIC
0000000000004000 d _GLOBAL_OFFSET_TABLE_
[hjl@gnu-cfl-1 order-1]$
---
 ld/ld.h               |  3 +++
 ld/ldfile.c           | 21 +++++++++++++++++++++
 ld/ldlex.h            |  1 +
 ld/lexsup.c           |  6 ++++++
 ld/scripttempl/elf.sc |  2 ++
 5 files changed, 33 insertions(+)

diff --git a/ld/ld.h b/ld/ld.h
index 55078a9637..05a4bef175 100644
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -321,6 +321,9 @@ typedef struct
 
   /* If set, print discarded sections in map file output.  */
   bfd_boolean print_map_discarded;
+
+  /* The optional section ordering file.  */
+  const char *section_ordering_file;
 } ld_config_type;
 
 extern ld_config_type config;
diff --git a/ld/ldfile.c b/ld/ldfile.c
index fcadc08c73..cf80474539 100644
--- a/ld/ldfile.c
+++ b/ld/ldfile.c
@@ -592,10 +592,31 @@ ldfile_open_command_file_1 (const char *name, bfd_boolean default_only)
 {
   FILE *ldlex_input_stack;
   bfd_boolean sysrooted;
+  bfd_boolean check_file;
 
   ldlex_input_stack = ldfile_find_command_file (name, default_only, &sysrooted);
 
   if (ldlex_input_stack == NULL)
+    {
+      check_file = TRUE;
+      if (strcmp (name, "config.section_ordering_file") == 0)
+	{
+	  if (config.section_ordering_file == NULL)
+	    check_file = FALSE;
+	  else
+	    {
+	      name = config.section_ordering_file;
+	      ldlex_input_stack = ldfile_find_command_file (name,
+							    default_only,
+							    &sysrooted);
+	      check_file = ldlex_input_stack == NULL;
+	    }
+	}
+    }
+  else
+    check_file = FALSE;
+
+  if (check_file)
     {
       bfd_set_error (bfd_error_system_call);
       einfo (_("%F%P: cannot open linker script file %s: %E\n"), name);
diff --git a/ld/ldlex.h b/ld/ldlex.h
index 32a7a6409e..e174228682 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -61,6 +61,7 @@ enum option_values
   OPTION_SONAME,
   OPTION_SORT_COMMON,
   OPTION_SORT_SECTION,
+  OPTION_SECTION_ORDERING_FILE,
   OPTION_STATS,
   OPTION_SYMBOLIC,
   OPTION_SYMBOLIC_FUNCTIONS,
diff --git a/ld/lexsup.c b/ld/lexsup.c
index dacb9623b4..27d3fb9cb6 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -441,6 +441,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 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 },
@@ -1229,6 +1232,9 @@ parse_args (unsigned argc, char **argv)
 	    einfo (_("%F%P: invalid section sorting option: %s\n"),
 		   optarg);
 	  break;
+	case OPTION_SECTION_ORDERING_FILE:
+	  config.section_ordering_file = optarg;
+	  break;
 	case OPTION_STATS:
 	  config.stats = TRUE;
 	  break;
diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc
index f9f0f7d402..e24f263ef9 100644
--- a/ld/scripttempl/elf.sc
+++ b/ld/scripttempl/elf.sc
@@ -513,6 +513,7 @@ cat <<EOF
     ${RELOCATING+*(.text.unlikely .text.*_unlikely .text.unlikely.*)}
     ${RELOCATING+*(.text.exit .text.exit.*)}
     ${RELOCATING+*(.text.startup .text.startup.*)}
+    ${RELOCATING+INCLUDE config.section_ordering_file;}
     ${RELOCATING+*(.text.hot .text.hot.*)}
     *(.text .stub${RELOCATING+ .text.* .gnu.linkonce.t.*})
     /* .gnu.warning sections are handled specially by elf32.em.  */
@@ -622,6 +623,7 @@ cat <<EOF
   .data         ${RELOCATING-0} :
   {
     ${RELOCATING+${DATA_START_SYMBOLS}}
+    ${RELOCATING+INCLUDE config.section_ordering_file;}
     *(.data${RELOCATING+ .data.* .gnu.linkonce.d.*})
     ${CONSTRUCTING+SORT(CONSTRUCTORS)}
   }
-- 
2.20.1



More information about the Binutils mailing list