Add SORT_NONE to .init and .fini in scripts

Message ID 20190321114746.GZ20126@bubble.grove.modra.org
State New
Headers show
Series
  • Add SORT_NONE to .init and .fini in scripts
Related show

Commit Message

Alan Modra March 21, 2019, 11:47 a.m.
The special case for .init and .fini in update_wild_statements is
ineffective for .init or .fini wildcards inside other output sections.
The special case needs to be on the wildcard, not the output section.
This patch is belt and braces, both fixing update_wild_statements and
the scripts.

	* scripttempl/alpha.sc, * scripttempl/armbpabi.sc,
	* scripttempl/crisaout.sc, * scripttempl/elf32cr16.sc,
	* scripttempl/elf32crx.sc, * scripttempl/elf32xc16x.sc,
	* scripttempl/elf32xc16xl.sc, * scripttempl/elf32xc16xs.sc,
	* scripttempl/elf64hppa.sc, * scripttempl/elf_chaos.sc,
	* scripttempl/elfarc.sc, * scripttempl/elfarcv2.sc,
	* scripttempl/elfd30v.sc, * scripttempl/elfm68hc11.sc,
	* scripttempl/elfm68hc12.sc, * scripttempl/elfm9s12z.sc,
	* scripttempl/elfmicroblaze.sc, * scripttempl/elfxgate.sc,
	* scripttempl/elfxtensa.sc, * scripttempl/epiphany_4x4.sc,
	* scripttempl/ft32.sc, * scripttempl/i386beos.sc,
	* scripttempl/iq2000.sc, * scripttempl/mcorepe.sc,
	* scripttempl/mep.sc, * scripttempl/mips.sc, * scripttempl/moxie.sc,
	* scripttempl/pe.sc, * scripttempl/pep.sc, * scripttempl/ppcpe.sc,
	* scripttempl/tic4xcoff.sc, * scripttempl/tic80coff.sc,
	* scripttempl/v850.sc, * scripttempl/v850_rh850.sc,
	* scripttempl/visium.sc, * scripttempl/xstormy16.sc: Add KEEP and
	SORT_NONE to .init and .fini wildcards.
	* scripttempl/elf32xc16x.sc,
	* scripttempl/elf32xc16xl.sc,
	* scripttempl/elf32xc16xs.sc: Add .fini wildcard.
	* scripttempl/elf_chaos.sc: Add .init output section.
	* scripttempl/elfd30v.sc: Remove duplicate .init.
	* scripttempl/elfm68hc11.sc, * scripttempl/elfm68hc12.sc,
	* scripttempl/elfm9s12z.sc, * scripttempl/elfxgate.sc: Remove
	duplicate .init, and add .fini wildcard.
	* scripttempl/ppcpe.sc (INIT, FINI): Delete.
	* ldlang.c (update_wild_statements): Special case .init and
	.fini in the wildcard, not the output section.


-- 
Alan Modra
Australia Development Lab, IBM

Patch

diff --git a/ld/ldlang.c b/ld/ldlang.c
index 77d890eb70..1952d4a475 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -3744,7 +3744,9 @@  update_wild_statements (lang_statement_union_type *s)
 	    case lang_wild_statement_enum:
 	      for (sec = s->wild_statement.section_list; sec != NULL;
 		   sec = sec->next)
-		{
+		/* Don't sort .init/.fini sections.  */
+		if (strcmp (sec->spec.name, ".init") != 0
+		    && strcmp (sec->spec.name, ".fini") != 0)
 		  switch (sec->spec.sorted)
 		    {
 		    case none:
@@ -3761,7 +3763,6 @@  update_wild_statements (lang_statement_union_type *s)
 		    default:
 		      break;
 		    }
-		}
 	      break;
 
 	    case lang_constructors_statement_enum:
@@ -3769,11 +3770,8 @@  update_wild_statements (lang_statement_union_type *s)
 	      break;
 
 	    case lang_output_section_statement_enum:
-	      /* Don't sort .init/.fini sections.  */
-	      if (strcmp (s->output_section_statement.name, ".init") != 0
-		  && strcmp (s->output_section_statement.name, ".fini") != 0)
-		update_wild_statements
-		  (s->output_section_statement.children.head);
+	      update_wild_statements
+		(s->output_section_statement.children.head);
 	      break;
 
 	    case lang_group_statement_enum:
diff --git a/ld/scripttempl/alpha.sc b/ld/scripttempl/alpha.sc
index d0c7c71d3a..d1d978d7ec 100644
--- a/ld/scripttempl/alpha.sc
+++ b/ld/scripttempl/alpha.sc
@@ -34,12 +34,12 @@  SECTIONS
   .text : {
     ${RELOCATING+ _ftext = .;}
     ${RELOCATING+ __istart = .;}
-    ${RELOCATING+ *(.init)}
+    ${RELOCATING+ KEEP (*(SORT_NONE(.init)))}
     ${RELOCATING+ LONG (0x6bfa8001)}
     ${RELOCATING+ eprol = .;}
     *(.text)
     ${RELOCATING+ __fstart = .;}
-    ${RELOCATING+ *(.fini)}
+    ${RELOCATING+ KEEP (*(SORT_NONE(.fini)))}
     ${RELOCATING+ LONG (0x6bfa8001)}
     ${RELOCATING+ _etext = .;}
   }
diff --git a/ld/scripttempl/armbpabi.sc b/ld/scripttempl/armbpabi.sc
index a573a1db08..cb71b557d3 100644
--- a/ld/scripttempl/armbpabi.sc
+++ b/ld/scripttempl/armbpabi.sc
@@ -208,7 +208,7 @@  cat <<EOF
   .init         ${RELOCATING-0} :
   {
     ${RELOCATING+${INIT_START}}
-    KEEP (*(.init))
+    KEEP (*(SORT_NONE(.init)))
     ${RELOCATING+${INIT_END}}
   } =${NOP-0}
   .text         ${RELOCATING-0} :
@@ -222,7 +222,7 @@  cat <<EOF
   .fini         ${RELOCATING-0} :
   {
     ${RELOCATING+${FINI_START}}
-    KEEP (*(.fini))
+    KEEP (*(SORT_NONE(.fini)))
     ${RELOCATING+${FINI_END}}
   } =${NOP-0}
   /* The SymbianOS kernel requires that the PLT go at the end of the
diff --git a/ld/scripttempl/crisaout.sc b/ld/scripttempl/crisaout.sc
index 5cb59e141c..9a9cf78d81 100644
--- a/ld/scripttempl/crisaout.sc
+++ b/ld/scripttempl/crisaout.sc
@@ -42,7 +42,7 @@  SECTIONS
     ${CONSTRUCTING+ PROVIDE (___do_global_ctors = .);}
     ${CONSTRUCTING+ SHORT (0xe1fc); /* push srp */}
     ${CONSTRUCTING+ SHORT (0xbe7e);}
-    ${CONSTRUCTING+ *(.init)}
+    ${CONSTRUCTING+ KEEP (*(SORT_NONE(.init)))}
     ${CONSTRUCTING+ SHORT (0x0d3e); /* jump [sp+] */}
     ${CONSTRUCTING+ PROVIDE (__init__end = .);}
     ${CONSTRUCTING+ PROVIDE (___init__end = .);}
@@ -52,7 +52,7 @@  SECTIONS
     ${CONSTRUCTING+ PROVIDE (___do_global_dtors = .);}
     ${CONSTRUCTING+ SHORT (0xe1fc); /* push srp */}
     ${CONSTRUCTING+ SHORT (0xbe7e);}
-    ${CONSTRUCTING+ *(.fini)}
+    ${CONSTRUCTING+ KEEP (*(SORT_NONE(.fini)))}
     ${CONSTRUCTING+ SHORT (0x0d3e); /* jump [sp+] */}
     ${CONSTRUCTING+ PROVIDE (__fini__end = .);}
     ${CONSTRUCTING+  ___fini__end = .;}
diff --git a/ld/scripttempl/elf32cr16.sc b/ld/scripttempl/elf32cr16.sc
index 9ae6bc2557..0da4603618 100644
--- a/ld/scripttempl/elf32cr16.sc
+++ b/ld/scripttempl/elf32cr16.sc
@@ -62,14 +62,14 @@  SECTIONS
   .init :
   {
     __INIT_START = .;
-    KEEP (*(.init))
+    KEEP (*(SORT_NONE(.init)))
     __INIT_END = .;
   }${RELOCATING+ > rom}
 
   .fini :
   {
     __FINI_START = .;
-    KEEP (*(.fini))
+    KEEP (*(SORT_NONE(.fini)))
     __FINI_END = .;
   }${RELOCATING+ > rom}
 
diff --git a/ld/scripttempl/elf32crx.sc b/ld/scripttempl/elf32crx.sc
index 46acea1799..64fefda120 100644
--- a/ld/scripttempl/elf32crx.sc
+++ b/ld/scripttempl/elf32crx.sc
@@ -58,14 +58,14 @@  SECTIONS
   .init :
   {
     __INIT_START = .;
-    KEEP (*(.init))
+    KEEP (*(SORT_NONE(.init)))
     __INIT_END = .;
   } > rom
 
   .fini :
   {
     __FINI_START = .;
-    KEEP (*(.fini))
+    KEEP (*(SORT_NONE(.fini)))
     __FINI_END = .;
   } > rom
 
diff --git a/ld/scripttempl/elf32xc16x.sc b/ld/scripttempl/elf32xc16x.sc
index b4325585fd..a451d41b9a 100644
--- a/ld/scripttempl/elf32xc16x.sc
+++ b/ld/scripttempl/elf32xc16x.sc
@@ -38,7 +38,8 @@  SECTIONS
 {
 .init :
 	{
-	  *(.init)
+	  KEEP (*(SORT_NONE(.init)))
+	  ${RELOCATING+KEEP (*(SORT_NONE(.fini)))}
 	} ${RELOCATING+ >introm}
 
 .text :
diff --git a/ld/scripttempl/elf32xc16xl.sc b/ld/scripttempl/elf32xc16xl.sc
index 3b6a5164ad..9dca52d9f5 100644
--- a/ld/scripttempl/elf32xc16xl.sc
+++ b/ld/scripttempl/elf32xc16xl.sc
@@ -40,7 +40,8 @@  SECTIONS
 	} ${RELOCATING+ > vectarea} */
 .init :
 	{
-	  *(.init)
+	  KEEP (*(SORT_NONE(.init)))
+	  ${RELOCATING+KEEP (*(SORT_NONE(.fini)))}
 	} ${RELOCATING+ >introm}
 
 .text :
diff --git a/ld/scripttempl/elf32xc16xs.sc b/ld/scripttempl/elf32xc16xs.sc
index 856991827f..d3eec11ad3 100644
--- a/ld/scripttempl/elf32xc16xs.sc
+++ b/ld/scripttempl/elf32xc16xs.sc
@@ -41,7 +41,8 @@  SECTIONS
 	} ${RELOCATING+ > vectarea} */
 .init :
 	{
-	  *(.init)
+	  KEEP (*(SORT_NONE(.init)))
+	  ${RELOCATING+KEEP (*(SORT_NONE(.fini)))}
 	} ${RELOCATING+ >introm}
 
 .text :
diff --git a/ld/scripttempl/elf64hppa.sc b/ld/scripttempl/elf64hppa.sc
index 89271bbca8..ee8fb93bba 100644
--- a/ld/scripttempl/elf64hppa.sc
+++ b/ld/scripttempl/elf64hppa.sc
@@ -403,7 +403,7 @@  cat <<EOF
   .init         ${RELOCATING-0} :
   {
     ${RELOCATING+${INIT_START}}
-    KEEP (*(.init))
+    KEEP (*(SORT_NONE(.init)))
     ${RELOCATING+${INIT_END}}
   } =${NOP-0}
 
@@ -420,7 +420,7 @@  cat <<EOF
   .fini         ${RELOCATING-0} :
   {
     ${RELOCATING+${FINI_START}}
-    KEEP (*(.fini))
+    KEEP (*(SORT_NONE(.fini)))
     ${RELOCATING+${FINI_END}}
   } =${NOP-0}
   ${RELOCATING+PROVIDE (__${ETEXT_NAME} = .);}
diff --git a/ld/scripttempl/elf_chaos.sc b/ld/scripttempl/elf_chaos.sc
index c26c508b9e..1cc63b63dd 100644
--- a/ld/scripttempl/elf_chaos.sc
+++ b/ld/scripttempl/elf_chaos.sc
@@ -251,10 +251,16 @@  cat <<EOF
     *(.gnu.warning)
     ${RELOCATING+${OTHER_TEXT_SECTIONS}}
   } =${NOP-0}
+  .init         ${RELOCATING-0} :
+  {
+    ${RELOCATING+${INIT_START}}
+    KEEP (*(SORT_NONE(.init)))
+    ${RELOCATING+${INIT_END}}
+  } =${NOP-0}
   .fini         ${RELOCATING-0} :
   {
     ${RELOCATING+${FINI_START}}
-    KEEP (*(.fini))
+    KEEP (*(SORT_NONE(.fini)))
     ${RELOCATING+${FINI_END}}
   } =${NOP-0}
   ${RELOCATING+PROVIDE (__etext = .);}
diff --git a/ld/scripttempl/elfarc.sc b/ld/scripttempl/elfarc.sc
index 5738de31d1..79d9924092 100644
--- a/ld/scripttempl/elfarc.sc
+++ b/ld/scripttempl/elfarc.sc
@@ -257,7 +257,7 @@  cat <<EOF
   .init         ${RELOCATING-0} :
   {
     ${RELOCATING+${INIT_START}}
-    KEEP (*(.init))
+    KEEP (*(SORT_NONE(.init)))
     ${RELOCATING+${INIT_END}}
   } =${NOP-0}
 
@@ -283,7 +283,7 @@  cat <<EOF
   .fini         ${RELOCATING-0} :
   {
     ${RELOCATING+${FINI_START}}
-    KEEP (*(.fini))
+    KEEP (*(SORT_NONE(.fini)))
     ${RELOCATING+${FINI_END}}
   } =${NOP-0}
   ${RELOCATING+PROVIDE (__etext = .);}
diff --git a/ld/scripttempl/elfarcv2.sc b/ld/scripttempl/elfarcv2.sc
index 1027123eec..9b55333dc1 100644
--- a/ld/scripttempl/elfarcv2.sc
+++ b/ld/scripttempl/elfarcv2.sc
@@ -196,7 +196,7 @@  SECTIONS
   .init         ${RELOCATING-0} :
   {
     ${RELOCATING+${INIT_START}}
-    KEEP (*(.init))
+    KEEP (*(SORT_NONE(.init)))
     ${RELOCATING+${INIT_END}}
   } ${RELOCATING+ > ${TEXT_MEMORY}}  =${NOP-0}
 
@@ -215,7 +215,7 @@  SECTIONS
   .fini         ${RELOCATING-0} :
   {
     ${RELOCATING+${FINI_START}}
-    KEEP (*(.fini))
+    KEEP (*(SORT_NONE(.fini)))
     ${RELOCATING+${FINI_END}}
 
     ${RELOCATING+PROVIDE (__etext = .);}
diff --git a/ld/scripttempl/elfd30v.sc b/ld/scripttempl/elfd30v.sc
index c2b3ebabdb..e324c60109 100644
--- a/ld/scripttempl/elfd30v.sc
+++ b/ld/scripttempl/elfd30v.sc
@@ -116,7 +116,7 @@  SECTIONS
   .rel.plt		${RELOCATING-0} : { *(.rel.plt) }
   .rela.plt		${RELOCATING-0} : { *(.rela.plt) }
 
-  .init			${RELOCATING-0} : { *(.init) } =${NOP-0}
+  .init			${RELOCATING-0} : { KEEP (*(SORT_NONE(.init))) } =${NOP-0}
   ${DATA_PLT-${PLT}}
 
   /* Internal text space */
@@ -127,8 +127,7 @@  SECTIONS
   {
     *(.text)
     ${RELOCATING+*(.gnu.linkonce.t*)
-    *(SORT_NONE(.init))
-    *(SORT_NONE(.fini))
+    KEEP (*(SORT_NONE(.fini)))
     _etext = . ;}
   } ${RELOCATING+ > ${TEXT_MEMORY}}
 
diff --git a/ld/scripttempl/elfm68hc11.sc b/ld/scripttempl/elfm68hc11.sc
index f5406f40c2..dc3f14eae5 100644
--- a/ld/scripttempl/elfm68hc11.sc
+++ b/ld/scripttempl/elfm68hc11.sc
@@ -307,7 +307,7 @@  SECTIONS
 
   .init	${RELOCATING-0} :
   {
-    *(.init)
+    KEEP (*(SORT_NONE(.init)))
   } ${RELOCATING+=${NOP-0}}
 
   ${RELOCATING-${INSTALL_RELOC}}
@@ -318,7 +318,6 @@  SECTIONS
     /* Put startup code at beginning so that _start keeps same address.  */
     ${RELOCATING+${STARTUP_CODE}}
 
-    ${RELOCATING+*(.init)}
     *(.text)
     ${RELOCATING+*(.text.*)}
     /* .gnu.warning sections are handled specially by elf32.em.  */
@@ -327,6 +326,7 @@  SECTIONS
     ${RELOCATING+*(.tramp)}
     ${RELOCATING+*(.tramp.*)}
 
+    ${RELOCATING+KEEP (*(SORT_NONE(.fini)))}
     ${RELOCATING+${FINISH_CODE}}
 
     ${RELOCATING+_etext = .;}
diff --git a/ld/scripttempl/elfm68hc12.sc b/ld/scripttempl/elfm68hc12.sc
index 5c68ffffa5..9f8d92aeae 100644
--- a/ld/scripttempl/elfm68hc12.sc
+++ b/ld/scripttempl/elfm68hc12.sc
@@ -306,7 +306,7 @@  SECTIONS
 
   .init	${RELOCATING-0} :
   {
-    *(.init)
+    KEEP (*(SORT_NONE(.init)))
   } ${RELOCATING+=${NOP-0}}
 
   ${RELOCATING-${INSTALL_RELOC}}
@@ -317,7 +317,6 @@  SECTIONS
     /* Put startup code at beginning so that _start keeps same address.  */
     ${RELOCATING+${STARTUP_CODE}}
 
-    ${RELOCATING+*(.init)}
     *(.text)
     ${RELOCATING+*(.text.*)}
     /* .gnu.warning sections are handled specially by elf32.em.  */
@@ -326,6 +325,7 @@  SECTIONS
     ${RELOCATING+*(.tramp)}
     ${RELOCATING+*(.tramp.*)}
 
+    ${RELOCATING+KEEP (*(SORT_NONE(.fini)))}
     ${RELOCATING+${FINISH_CODE}}
 
     ${RELOCATING+_etext = .;}
diff --git a/ld/scripttempl/elfm9s12z.sc b/ld/scripttempl/elfm9s12z.sc
index 3fd14e93f6..d640882c17 100644
--- a/ld/scripttempl/elfm9s12z.sc
+++ b/ld/scripttempl/elfm9s12z.sc
@@ -292,7 +292,7 @@  SECTIONS
 
   .init	${RELOCATING-0} :
   {
-    *(.init)
+    KEEP (*(SORT_NONE(.init)))
   } ${RELOCATING+=${NOP-0}}
 
   ${RELOCATING-${INSTALL_RELOC}}
@@ -303,7 +303,6 @@  SECTIONS
     /* Put startup code at beginning so that _start keeps same address.  */
     ${RELOCATING+${STARTUP_CODE}}
 
-    ${RELOCATING+*(.init)}
     *(.text)
     ${RELOCATING+*(.text.*)}
     /* .gnu.warning sections are handled specially by elf32.em.  */
@@ -312,6 +311,7 @@  SECTIONS
     ${RELOCATING+*(.tramp)}
     ${RELOCATING+*(.tramp.*)}
 
+    ${RELOCATING+KEEP (*(SORT_NONE(.fini)))}
     ${RELOCATING+${FINISH_CODE}}
 
     ${RELOCATING+_etext = .;}
diff --git a/ld/scripttempl/elfmicroblaze.sc b/ld/scripttempl/elfmicroblaze.sc
index 30b9c28670..989b7fd9ae 100644
--- a/ld/scripttempl/elfmicroblaze.sc
+++ b/ld/scripttempl/elfmicroblaze.sc
@@ -85,8 +85,8 @@  SECTIONS
   }
   ${RELOCATING+ _etext  =  .;}
 
-  .init : { KEEP (*(.init))	} =0
-  .fini : { KEEP (*(.fini))	} =0
+  .init : { KEEP (*(SORT_NONE(.init)))	} =0
+  .fini : { KEEP (*(SORT_NONE(.fini)))	} =0
 
   ${RELOCATING+PROVIDE (__CTOR_LIST__ = .);}
   ${RELOCATING+PROVIDE (___CTOR_LIST__ = .);}
diff --git a/ld/scripttempl/elfxgate.sc b/ld/scripttempl/elfxgate.sc
index fe16e814df..fd6c0738e4 100644
--- a/ld/scripttempl/elfxgate.sc
+++ b/ld/scripttempl/elfxgate.sc
@@ -306,7 +306,7 @@  SECTIONS
 
   .init	${RELOCATING-0} :
   {
-    *(.init)
+    KEEP (*(SORT_NONE(.init)))
   } ${RELOCATING+=${NOP-0}}
 
   ${RELOCATING-${INSTALL_RELOC}}
@@ -317,7 +317,6 @@  SECTIONS
     /* Put startup code at beginning so that _start keeps same address.  */
     ${RELOCATING+${STARTUP_CODE}}
 
-    ${RELOCATING+*(.init)}
     *(.text)
     ${RELOCATING+*(.text.*)}
     /* .gnu.warning sections are handled specially by elf32.em.  */
@@ -326,6 +325,7 @@  SECTIONS
     ${RELOCATING+*(.tramp)}
     ${RELOCATING+*(.tramp.*)}
 
+    ${RELOCATING+KEEP (*(SORT_NONE(.fini)))}
     ${RELOCATING+${FINISH_CODE}}
 
     ${RELOCATING+_etext = .;}
diff --git a/ld/scripttempl/elfxtensa.sc b/ld/scripttempl/elfxtensa.sc
index ef1eee258b..e81cb98375 100644
--- a/ld/scripttempl/elfxtensa.sc
+++ b/ld/scripttempl/elfxtensa.sc
@@ -147,9 +147,9 @@  RODATA=".rodata       ${RELOCATING-0} : { *(.rodata${RELOCATING+ .rodata.* .gnu.
 DATARELRO=".data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }"
 DISCARDED="/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink)  *(.gnu.lto_*) }"
 INIT_LIT=".init.literal 0 : { *(.init.literal)	}"
-INIT=".init         0 : { *(.init)		}"
+INIT=".init         0 : { KEEP (*(SORT_NONE(.init))) }"
 FINI_LIT=".fini.literal 0 : { *(.fini.literal)	}"
-FINI=".fini         0 : { *(.fini)		}"
+FINI=".fini         0 : { KEEP (*(SORT_NONE(.fini))) }"
 if test -z "${NO_SMALL_DATA}"; then
   SBSS=".sbss         ${RELOCATING-0} :
   {
diff --git a/ld/scripttempl/epiphany_4x4.sc b/ld/scripttempl/epiphany_4x4.sc
index 3156926342..f86ce89dd3 100644
--- a/ld/scripttempl/epiphany_4x4.sc
+++ b/ld/scripttempl/epiphany_4x4.sc
@@ -472,7 +472,7 @@  cat <<EOF
   .init  ${RELOCATING-0}${RELOCATING+__init_start}  :
   {
     ${RELOCATING+${INIT_START}}
-    KEEP (*(.init))
+    KEEP (*(SORT_NONE(.init)))
     ${RELOCATING+${INIT_END}}
   } /* ${RELOCATING+ > INTERNAL_RAM} */ =${NOP-0}
 
@@ -482,7 +482,7 @@  cat <<EOF
   .fini ${RELOCATING-0}${RELOCATING+ADDR(.init)+SIZEOF(.init)} :
   {
     ${RELOCATING+${FINI_START}}
-    KEEP (*(.fini))
+    KEEP (*(SORT_NONE(.fini)))
     ${RELOCATING+${FINI_END}}
   } /* ${RELOCATING+ > INTERNAL_RAM} */ =${NOP-0}
 
diff --git a/ld/scripttempl/ft32.sc b/ld/scripttempl/ft32.sc
index 2d7d647694..ef7f332aa5 100644
--- a/ld/scripttempl/ft32.sc
+++ b/ld/scripttempl/ft32.sc
@@ -35,8 +35,8 @@  SECTIONS
     *(.text${RELOCATING+*})
     ${RELOCATING+*(.strings)
     *(._pm*)
-    *(.init)
-    *(.fini)
+    KEEP (*(SORT_NONE(.init)))
+    KEEP (*(SORT_NONE(.fini)))
     _etext = .;
     . = ALIGN(4);}
   } ${RELOCATING+ > flash}
diff --git a/ld/scripttempl/i386beos.sc b/ld/scripttempl/i386beos.sc
index 47da2742ef..f4ce42ccde 100644
--- a/ld/scripttempl/i386beos.sc
+++ b/ld/scripttempl/i386beos.sc
@@ -59,7 +59,7 @@  SECTIONS
   .text ${RELOCATING+ __image_base__ + __section_alignment__ } :
   {
     ${RELOCATING+ __text_start__ = . ;}
-    ${RELOCATING+ *(.init)}
+    ${RELOCATING+ KEEP (*(SORT_NONE(.init)))}
     *(.text)
     ${R_TEXT}
     *(.glue_7t)
@@ -68,7 +68,7 @@  SECTIONS
 			LONG (-1); *(.ctors); *(.ctor); LONG (0); }
     ${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
 			LONG (-1); *(.dtors); *(.dtor);  LONG (0); }
-    ${RELOCATING+ *(.fini)}
+    ${RELOCATING+ KEEP (*(SORT_NONE(.fini)))}
     /* ??? Why is .gcc_exc here?  */
     ${RELOCATING+ *(.gcc_exc)}
     ${RELOCATING+ etext = .;}
diff --git a/ld/scripttempl/iq2000.sc b/ld/scripttempl/iq2000.sc
index f2ee794a3f..2f988ec4aa 100644
--- a/ld/scripttempl/iq2000.sc
+++ b/ld/scripttempl/iq2000.sc
@@ -289,7 +289,7 @@  cat <<EOF
   .init        ${RELOCATING-0} :
   {
     ${RELOCATING+${INIT_START}}
-    KEEP (*(.init))
+    KEEP (*(SORT_NONE(.init)))
     ${RELOCATING+${INIT_END}}
   } =${NOP-0}
 
@@ -308,7 +308,7 @@  cat <<EOF
   .fini    ${RELOCATING-0} :
   {
     ${RELOCATING+${FINI_START}}
-    KEEP (*(.fini))
+    KEEP (*(SORT_NONE(.fini)))
     ${RELOCATING+${FINI_END}}
   } =${NOP-0}
   ${RELOCATING+PROVIDE (__etext = .);}
diff --git a/ld/scripttempl/mcorepe.sc b/ld/scripttempl/mcorepe.sc
index 45285dc181..e7cf3d3544 100644
--- a/ld/scripttempl/mcorepe.sc
+++ b/ld/scripttempl/mcorepe.sc
@@ -65,7 +65,7 @@  SECTIONS
 {
   .text ${RELOCATING+ __image_base__ + __section_alignment__ } :
   {
-    ${RELOCATING+ *(.init)}
+    ${RELOCATING+ KEEP (*(SORT_NONE(.init)))}
     *(.text)
     ${R_TEXT}
     ${RELOCATING+ *(.text.*)}
@@ -75,7 +75,7 @@  SECTIONS
 			LONG (-1); *(.ctors); *(.ctor); LONG (0); }
     ${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
 			LONG (-1); *(.dtors); *(.dtor);  LONG (0); }
-    ${RELOCATING+ *(.fini)}
+    ${RELOCATING+ KEEP (*(SORT_NONE(.fini)))}
     /* ??? Why is .gcc_exc here?  */
     ${RELOCATING+ *(.gcc_exc)}
     ${RELOCATING+ etext = .;}
diff --git a/ld/scripttempl/mep.sc b/ld/scripttempl/mep.sc
index 3ce39ff212..139d1b83b1 100644
--- a/ld/scripttempl/mep.sc
+++ b/ld/scripttempl/mep.sc
@@ -302,7 +302,7 @@  cat <<EOF
   .init         ${RELOCATING-0} :
   {
     ${RELOCATING+${INIT_START}}
-    KEEP (*(.init))
+    KEEP (*(SORT_NONE(.init)))
     ${RELOCATING+${INIT_END}}
   } =${NOP-0}
 
@@ -318,7 +318,7 @@  cat <<EOF
   .fini         ${RELOCATING-0} :
   {
     ${RELOCATING+${FINI_START}}
-    KEEP (*(.fini))
+    KEEP (*(SORT_NONE(.fini)))
     ${RELOCATING+${FINI_END}}
   } =${NOP-0}
   ${RELOCATING+PROVIDE (__etext = .);}
diff --git a/ld/scripttempl/mips.sc b/ld/scripttempl/mips.sc
index 3b080d3da6..7de30bdc74 100644
--- a/ld/scripttempl/mips.sc
+++ b/ld/scripttempl/mips.sc
@@ -40,13 +40,13 @@  SECTIONS
 {
   ${RELOCATING+. = ${TEXT_START_ADDR};}
   .text : {
-    ${RELOCATING+ _ftext = . };
-    *(.init)
-    ${RELOCATING+ eprol  =  .};
+    ${RELOCATING+_ftext = .;
+    KEEP (*(SORT_NONE(.init)))
+    eprol  =  .;}
     *(.text)
-    *(.fini)
-    ${RELOCATING+ etext  =  .};
-    ${RELOCATING+ _etext  =  .};
+    ${RELOCATING+KEEP (*(SORT_NONE(.fini)))
+    etext  =  .;
+    _etext  =  .;}
   }
   ${RELOCATING+. = ${DATA_ADDR};}
   .rdata : {
diff --git a/ld/scripttempl/moxie.sc b/ld/scripttempl/moxie.sc
index bdb63277d1..fbfc832ca5 100644
--- a/ld/scripttempl/moxie.sc
+++ b/ld/scripttempl/moxie.sc
@@ -29,10 +29,10 @@  SECTIONS
   .text :
   {
     *(.text)
-      .init : { KEEP (*(.init)) } =0
-      .fini : { KEEP (*(.fini)) } =0
+    ${RELOCATING+KEEP (*(SORT_NONE(.init)))
+    KEEP (*(SORT_NONE(.fini)))
     *(.strings)
-    ${RELOCATING+ _etext = . ; }
+    _etext = . ; }
   } ${RELOCATING+ > ram}
   ${CONSTRUCTING+${TORS}}
   .data :
diff --git a/ld/scripttempl/pe.sc b/ld/scripttempl/pe.sc
index a9e64f6631..865ee58d91 100644
--- a/ld/scripttempl/pe.sc
+++ b/ld/scripttempl/pe.sc
@@ -90,7 +90,7 @@  SECTIONS
   ${RELOCATING+. = ALIGN(__section_alignment__);}
   .text ${RELOCATING+ __image_base__ + ( __section_alignment__ < ${TARGET_PAGE_SIZE} ? . : __section_alignment__ )} :
   {
-    ${RELOCATING+ KEEP(*(.init))}
+    ${RELOCATING+KEEP (*(SORT_NONE(.init)))}
     *(.text)
     ${R_TEXT}
     ${RELOCATING+ *(.text.*)}
@@ -133,7 +133,7 @@  SECTIONS
        KEEP(*(SORT_BY_NAME(.dtors.*)));
        LONG (0);
      }
-    ${RELOCATING+ KEEP (*(.fini))}
+    ${RELOCATING+KEEP (*(SORT_NONE(.fini)))}
     /* ??? Why is .gcc_exc here?  */
     ${RELOCATING+ *(.gcc_exc)}
     ${RELOCATING+PROVIDE (etext = .);}
diff --git a/ld/scripttempl/pep.sc b/ld/scripttempl/pep.sc
index 41e7962c3f..e6d594c2bb 100644
--- a/ld/scripttempl/pep.sc
+++ b/ld/scripttempl/pep.sc
@@ -90,7 +90,7 @@  SECTIONS
   ${RELOCATING+. = ALIGN(__section_alignment__);}
   .text ${RELOCATING+ __image_base__ + ( __section_alignment__ < ${TARGET_PAGE_SIZE} ? . : __section_alignment__ )} :
   {
-    ${RELOCATING+ KEEP(*(.init))}
+    ${RELOCATING+KEEP (*(SORT_NONE(.init)))}
     *(.text)
     ${R_TEXT}
     ${RELOCATING+ *(.text.*)}
@@ -134,7 +134,7 @@  SECTIONS
        KEEP (*(SORT_BY_NAME(.dtors.*)));
        LONG (0); LONG (0);
      }
-    ${RELOCATING+ KEEP (*(.fini))}
+    ${RELOCATING+KEEP (*(SORT_NONE(.fini)))}
     /* ??? Why is .gcc_exc here?  */
     ${RELOCATING+ *(.gcc_exc)}
     ${RELOCATING+PROVIDE (etext = .);}
diff --git a/ld/scripttempl/ppcpe.sc b/ld/scripttempl/ppcpe.sc
index bb2a093047..38920a17b6 100644
--- a/ld/scripttempl/ppcpe.sc
+++ b/ld/scripttempl/ppcpe.sc
@@ -8,11 +8,6 @@ 
 # are permitted in any medium without royalty provided the copyright
 # notice and this notice are preserved.
 #
-# These are substituted in as variables in order to get '}' in a shell
-# conditional expansion.
-
-INIT='.init : { *(.init) }'
-FINI='.fini : { *(.fini) }'
 
 cat <<EOF
 /* Copyright (C) 2014-2019 Free Software Foundation, Inc.
@@ -44,7 +39,7 @@  SECTIONS
   /* text - the usual meaning */
   .text ${RELOCATING+ __image_base__ + __section_alignment__ } :
 	{
-	    ${RELOCATING+ *(.init);}
+	    ${RELOCATING+ KEEP (*(SORT_NONE(.init)))}
 	    *(.text)
 	    ${RELOCATING+ *(.text.*)}
 	    *(.gcc_except_table)
@@ -52,7 +47,7 @@  SECTIONS
 			LONG (-1); *(.ctors); *(.ctor); LONG (0); }
 	    ${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
 			LONG (-1); *(.dtors); *(.dtor); LONG (0); }
-	    ${RELOCATING+ *(.fini);}
+	    ${RELOCATING+ KEEP (*(SORT_NONE(.fini)))}
 	    ${RELOCATING+ etext = .};
 	}
 
diff --git a/ld/scripttempl/tic4xcoff.sc b/ld/scripttempl/tic4xcoff.sc
index f610f44fd5..2607a68fd7 100644
--- a/ld/scripttempl/tic4xcoff.sc
+++ b/ld/scripttempl/tic4xcoff.sc
@@ -109,7 +109,7 @@  SECTIONS
   /* Program code.  */
   .text : {
     ${RELOCATING+  __text =  .;}
-    ${RELOCATING+ *(.init)}
+    ${RELOCATING+ KEEP (*(SORT_NONE(.init)))}
     *(.text)
     ${CONSTRUCTING+ ___CTOR_LIST__ = .;}
     ${CONSTRUCTING+ LONG(___CTOR_END__ - ___CTOR_LIST__ - 2)}
@@ -121,7 +121,7 @@  SECTIONS
     ${CONSTRUCTING+ *(.dtors)}
     ${CONSTRUCTING+ LONG(0)}
     ${CONSTRUCTING+ ___DTOR_END__  = .;}
-    ${RELOCATING+ *(.fini)}
+    ${RELOCATING+ KEEP (*(SORT_NONE(.fini)))}
     ${RELOCATING+  __etext =  .;}
   } ${RELOCATING+ > ${TEXT_MEMORY}}
   /* Global initialised variables.  */
diff --git a/ld/scripttempl/tic80coff.sc b/ld/scripttempl/tic80coff.sc
index 9c0798ac5b..692227a8b4 100644
--- a/ld/scripttempl/tic80coff.sc
+++ b/ld/scripttempl/tic80coff.sc
@@ -40,8 +40,8 @@  ${RELOCATING+ENTRY (${ENTRY})}
 SECTIONS
 {
   .text ${RELOCATING+ $TEXT_START_ADDR} : {
-    *(.init)
-    *(.fini)
+    ${RELOCATING+KEEP (*(SORT_NONE(.init)))
+    KEEP (*(SORT_NONE(.fini)))}
     *(.text)
   }
   .const ALIGN(4) : {
diff --git a/ld/scripttempl/v850.sc b/ld/scripttempl/v850.sc
index 2a87e6deda..f961530d9c 100644
--- a/ld/scripttempl/v850.sc
+++ b/ld/scripttempl/v850.sc
@@ -71,7 +71,7 @@  SECTIONS
   .rela.bss	: { *(.rela.bss) }
   .rel.plt	: { *(.rel.plt) }
   .rela.plt	: { *(.rela.plt) }
-  .init		: { KEEP (*(.init)) } =0
+  .init		: { KEEP (*(SORT_NONE(.init))) } =0
   .plt		: { *(.plt) }
 
   .text		:
@@ -102,7 +102,7 @@  SECTIONS
     *(.call_table_text)
   }
 
-  .fini		: { KEEP (*(.fini)) } =0
+  .fini		: { KEEP (*(SORT_NONE(.fini))) } =0
   .rodata	: { *(.rodata) ${RELOCATING+*(.rodata.*) *(.gnu.linkonce.r*)} }
   .rodata1	: { *(.rodata1) }
 
diff --git a/ld/scripttempl/v850_rh850.sc b/ld/scripttempl/v850_rh850.sc
index 3d594d87b6..fc1a383e19 100644
--- a/ld/scripttempl/v850_rh850.sc
+++ b/ld/scripttempl/v850_rh850.sc
@@ -75,7 +75,7 @@  SECTIONS
   .rela.bss	: { *(.rela.bss) }
   .rel.plt	: { *(.rel.plt) }
   .rela.plt	: { *(.rela.plt) }
-  .init		: { KEEP (*(.init)) } =0
+  .init		: { KEEP (*(SORT_NONE(.init))) } =0
   .plt		: { *(.plt) }
 
   .text		:
@@ -106,7 +106,7 @@  SECTIONS
     *(.call_table_text)
   }
 
-  .fini		: { KEEP (*(.fini)) } =0
+  .fini		: { KEEP (*(SORT_NONE(.fini))) } =0
   .rodata	:
   {
 	*(.rodata)
diff --git a/ld/scripttempl/visium.sc b/ld/scripttempl/visium.sc
index 9e98429e0a..dfbe2c1c4a 100644
--- a/ld/scripttempl/visium.sc
+++ b/ld/scripttempl/visium.sc
@@ -60,8 +60,8 @@  cat <<EOF
 SECTIONS
 {
   .init ${RELOCATING-0} : {
-    KEEP (*(.init))
-    ${RELOCATING+KEEP (*(.fini))}
+    KEEP (*(SORT_NONE(.init)))
+    ${RELOCATING+KEEP (*(SORT_NONE(.fini)))}
     ${RELOCATING+ _einit  =  .;}
   } ${RELOCATING+ > init}
 
diff --git a/ld/scripttempl/xstormy16.sc b/ld/scripttempl/xstormy16.sc
index 820676720c..757e0b8fea 100644
--- a/ld/scripttempl/xstormy16.sc
+++ b/ld/scripttempl/xstormy16.sc
@@ -189,13 +189,13 @@  SECTIONS
   .init        ${RELOCATING-0} :
   {
     ${RELOCATING+${INIT_START}}
-    KEEP (*(.init))
+    KEEP (*(SORT_NONE(.init)))
     ${RELOCATING+${INIT_END}}
   }${RELOCATING+ > ROM =${NOP-0}}
   .fini    ${RELOCATING-0} :
   {
     ${RELOCATING+${FINI_START}}
-    KEEP (*(.fini))
+    KEEP (*(SORT_NONE(.fini)))
     ${RELOCATING+${FINI_END}}
   }${RELOCATING+ > ROM =${NOP-0}}
   ${RELOCATING+PROVIDE (__etext = .);}