[PATCH] ARM: Support .noinit and .persistent sections in ELF linker script

Jozef Lawrynowicz jozef.l@mittosystems.com
Thu Nov 26 18:13:56 GMT 2020


On Wed, Nov 25, 2020 at 01:40:49PM +0000, Jozef Lawrynowicz wrote:
> On Wed, Nov 25, 2020 at 12:36:25PM +0000, Nick Clifton via Binutils wrote:
> > Hi Jozef,
> > 
> > > > > Support for the "persistent" attribute, to place variables in the
> > > > > ".persistent" section, has been added to GCC and needs to be handled in
> > > > > the default ARM ELF linker script.
> > 
> > > > Are these sections ARM specific ?
> > 
> > > The sections are not ARM-specific, GCC supports the corresponding
> > > "persistent" and "noinit" attributes for all ELF targets. In the real
> > > world, the sections must be placed in some non-volatile type of
> > > writeable memory, so may not be supported for some targets.
> > > 
> > > In addition to ARM, it looks like AVR, ARC, MSP430, and PRU already
> > > support a .noinit section in their default linker scripts.
> > > .persistent is only used by MSP430 so far.
> > > 
> > > So I could move the definitions to elf.sc, as long as it would not be
> > > considered intrusive for targets using elf.sc as a base, but don't
> > > support .noinit or .persistent.
> > > 
> > > I would also then need to remove the corresponding .noinit output
> > > section from the above targets using elf.sc as a base linker script, so
> > > there aren't duplicate definitions of that output section.
> > 
> > If you are willing to take on this additional work and make this
> > change then I think that it would be a good idea.  Having generic
> > support for a feature used by more than a few targets makes sense
> > to me.  Plus cleaning up duplicated code is always useful.
> 
> I'm happy to do that, I'll put together a new patch soon.

Hi Nick,

I've attached a new patch with the new sections defined in elf.sc. They
are not included in the linker script by default, instead they are
optionally turned on by setting HAVE_{NOINIT,PERSISTENT}=yes.

Out of the targets already defining .noinit or .persistent in their
linker scripts, ARM is actually the only one using elf.sc as a base
script.

The sections are now also listed in the "special_sections" structure in
bfd/elf.c.

Successfully regtested for aarch64-elf arc-elf arm-eabi avr-elf
msp430-elf pru-elf x86_64-pc-linux-gnu, ok to apply?

Thanks,
Jozef
-------------- next part --------------
>From 0b9b556d948fede86bb8350ed6d2a1bfcc7b2a92 Mon Sep 17 00:00:00 2001
From: Jozef Lawrynowicz <jozef.l@mittosystems.com>
Date: Thu, 26 Nov 2020 17:55:13 +0000
Subject: [PATCH] ELF: Support .noinit and .persistent sections

The ".persistent" section is for data that should be initialized during
load, but not during application reset.

The ".noinit" section is for data that should not be initialized during
load or application reset.

Targets utilizing the elf.sc linked script template can define
HAVE_{NOINIT,PERSISTENT}=yes to include the .noinit or .persistent
output sections in the generated linker script.

Targets with existing support for .noinit did not handle unique
.noinit.* and .gnu.linkonce.n.* sections the .noinit output section,
this patch also fixes that.

bfd/ChangeLog:

	* elf.c (special_sections_g): Add .gnu.linkonce.n and .gnu.linkonce.p.
	(special_sections_n): Add .noinit.
	(special_sections_p): Add .persistent.

binutils/ChangeLog:

	* testsuite/lib/binutils-common.exp (supports_noinit_section): New.
	(supports_persistent_section): New.

gas/ChangeLog:

	* testsuite/gas/elf/elf.exp: Run new tests.
	* testsuite/gas/elf/section25.d: New test.
	* testsuite/gas/elf/section25.s: New test.
	* testsuite/gas/elf/section26.d: New test.
	* testsuite/gas/elf/section26.s: New test.

ld/ChangeLog:

	* emulparams/armelf.sh (OTHER_SECTIONS): Remove .noinit section
	definition.
	Define HAVE_{NOINIT,PERSISTENT}=yes.
	* scripttempl/avr.sc (.noinit): Add .noinit.* and .gnu.linkonce.n.*
	input section wildcard patterns.
	* scripttempl/elf.sc: Define .noinit and .persistent sections when
	HAVE_NOINIT or HAVE_PERSISTENT are defined to "yes".
	* scripttempl/elf32msp430.sc (.noinit): Add .noinit.* and
	.gnu.linkonce.n.*. input section wildcard patterns.
	(.persistent): Add .persistent.* and
	.gnu.linkonce.p.*. input section wildcard patterns.
	* scripttempl/elfarcv2.sc (.noinit): Add .noinit.* and
	.gnu.linkonce.n.*. input section wildcard patterns.
	* scripttempl/pru.sc: Likewise.
	* testsuite/ld-elf/noinit-sections-1.d: New test.
	* testsuite/ld-elf/noinit-sections-2.d: New test.
	* testsuite/ld-elf/noinit-sections-2.l: New test.
	* testsuite/ld-elf/noinit-sections.s: New test.
	* testsuite/ld-elf/persistent-sections-1.d: New test.
	* testsuite/ld-elf/persistent-sections-2.d: New test.
	* testsuite/ld-elf/persistent-sections-2.l: New test.
	* testsuite/ld-elf/persistent-sections.s: New test.
---
 bfd/elf.c                                   |  4 +++
 binutils/testsuite/lib/binutils-common.exp  | 39 +++++++++++++++++++++
 gas/testsuite/gas/elf/elf.exp               |  2 ++
 gas/testsuite/gas/elf/section25.d           | 12 +++++++
 gas/testsuite/gas/elf/section25.s           |  8 +++++
 gas/testsuite/gas/elf/section26.d           | 12 +++++++
 gas/testsuite/gas/elf/section26.s           |  8 +++++
 ld/emulparams/armelf.sh                     | 18 +++-------
 ld/scripttempl/avr.sc                       |  2 +-
 ld/scripttempl/elf.sc                       | 28 +++++++++++++++
 ld/scripttempl/elf32msp430.sc               | 12 +++++--
 ld/scripttempl/elfarcv2.sc                  |  2 +-
 ld/scripttempl/pru.sc                       |  2 +-
 ld/testsuite/ld-elf/noinit-sections-1.d     |  9 +++++
 ld/testsuite/ld-elf/noinit-sections-2.d     | 10 ++++++
 ld/testsuite/ld-elf/noinit-sections-2.l     |  5 +++
 ld/testsuite/ld-elf/noinit-sections.s       | 13 +++++++
 ld/testsuite/ld-elf/persistent-sections-1.d |  9 +++++
 ld/testsuite/ld-elf/persistent-sections-2.d | 10 ++++++
 ld/testsuite/ld-elf/persistent-sections-2.l |  5 +++
 ld/testsuite/ld-elf/persistent-sections.s   | 13 +++++++
 21 files changed, 205 insertions(+), 18 deletions(-)
 create mode 100644 gas/testsuite/gas/elf/section25.d
 create mode 100644 gas/testsuite/gas/elf/section25.s
 create mode 100644 gas/testsuite/gas/elf/section26.d
 create mode 100644 gas/testsuite/gas/elf/section26.s
 create mode 100644 ld/testsuite/ld-elf/noinit-sections-1.d
 create mode 100644 ld/testsuite/ld-elf/noinit-sections-2.d
 create mode 100644 ld/testsuite/ld-elf/noinit-sections-2.l
 create mode 100644 ld/testsuite/ld-elf/noinit-sections.s
 create mode 100644 ld/testsuite/ld-elf/persistent-sections-1.d
 create mode 100644 ld/testsuite/ld-elf/persistent-sections-2.d
 create mode 100644 ld/testsuite/ld-elf/persistent-sections-2.l
 create mode 100644 ld/testsuite/ld-elf/persistent-sections.s

diff --git a/bfd/elf.c b/bfd/elf.c
index dbff0f24c8..28621da915 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -2705,6 +2705,8 @@ static const struct bfd_elf_special_section special_sections_f[] =
 static const struct bfd_elf_special_section special_sections_g[] =
 {
   { STRING_COMMA_LEN (".gnu.linkonce.b"), -2, SHT_NOBITS,      SHF_ALLOC + SHF_WRITE },
+  { STRING_COMMA_LEN (".gnu.linkonce.n"), -2, SHT_NOBITS,      SHF_ALLOC + SHF_WRITE },
+  { STRING_COMMA_LEN (".gnu.linkonce.p"), -2, SHT_PROGBITS,    SHF_ALLOC + SHF_WRITE },
   { STRING_COMMA_LEN (".gnu.lto_"),	  -1, SHT_PROGBITS,    SHF_EXCLUDE },
   { STRING_COMMA_LEN (".got"),		   0, SHT_PROGBITS,    SHF_ALLOC + SHF_WRITE },
   { STRING_COMMA_LEN (".gnu.version"),	   0, SHT_GNU_versym,  0 },
@@ -2738,6 +2740,7 @@ static const struct bfd_elf_special_section special_sections_l[] =
 
 static const struct bfd_elf_special_section special_sections_n[] =
 {
+  { STRING_COMMA_LEN (".noinit"),	 -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
   { STRING_COMMA_LEN (".note.GNU-stack"), 0, SHT_PROGBITS, 0 },
   { STRING_COMMA_LEN (".note"),		 -1, SHT_NOTE,	   0 },
   { NULL,		     0,		  0, 0,		   0 }
@@ -2745,6 +2748,7 @@ static const struct bfd_elf_special_section special_sections_n[] =
 
 static const struct bfd_elf_special_section special_sections_p[] =
 {
+  { STRING_COMMA_LEN (".persistent"),	 -2, SHT_PROGBITS,	SHF_ALLOC + SHF_WRITE },
   { STRING_COMMA_LEN (".preinit_array"), -2, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE },
   { STRING_COMMA_LEN (".plt"),		  0, SHT_PROGBITS,	SHF_ALLOC + SHF_EXECINSTR },
   { NULL,		    0,		  0, 0,			0 }
diff --git a/binutils/testsuite/lib/binutils-common.exp b/binutils/testsuite/lib/binutils-common.exp
index a43639bafb..e83d1212ee 100644
--- a/binutils/testsuite/lib/binutils-common.exp
+++ b/binutils/testsuite/lib/binutils-common.exp
@@ -345,6 +345,45 @@ proc check_relro_support { } {
     return $relro_available_saved
 }
 
+# Check for support of the .noinit section, used for data that is not
+# initialized at load, or during the application's initialization sequence.
+proc supports_noinit_section {} {
+    # .noinit is only supported by ELF targets.
+    if { ![is_elf_format] } {
+	return 0;
+    }
+
+    # Targets that set HAVE_NOINIT=yes in their emulparams script utilizing
+    # elf.sc, or explicitly define a .noinit section in their linker script.
+    #
+    # arc-*-* is not included here, since it only supports .noinit with the
+    # non-default arcv2elf emulation.
+    if {[istarget "arm-*-*"]
+	  || [istarget "avr-*-*"]
+	  || [istarget "msp430-*-*"]
+	  || [istarget "pru-*-*"] } {
+	return 1;
+    }
+    return 0;
+}
+
+# Check for support of the .persistent section, used for data that is
+# initialized at load, but not during the application's initialization sequence.
+proc supports_persistent_section {} {
+    # .persistent is only supported by ELF targets.
+    if { ![is_elf_format] } {
+	return 0;
+    }
+
+    # Targets that set HAVE_PERSISTENT=yes in their emulparams script utilizing
+    # elf.sc, or explicitly define a .persistent section in their linker script.
+    if { [istarget "arm-*-*"]
+	  || [istarget "msp430-*-*"] } {
+	return 1;
+    }
+    return 0;
+}
+
 # Compare two files line-by-line.  FILE_1 is the actual output and FILE_2
 # is the expected output.  Ignore blank lines in either file.
 #
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index 0ba32c7362..25c40a2810 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -266,6 +266,8 @@ if { [is_elf_format] } then {
     run_dump_test "section23b"
     run_dump_test "section24a"
     run_dump_test "section24b"
+    run_dump_test "section25"
+    run_dump_test "section26"
     run_dump_test "sh-link-zero"
     run_dump_test "dwarf2-1" $dump_opts
     run_dump_test "dwarf2-2" $dump_opts
diff --git a/gas/testsuite/gas/elf/section25.d b/gas/testsuite/gas/elf/section25.d
new file mode 100644
index 0000000000..09353849e5
--- /dev/null
+++ b/gas/testsuite/gas/elf/section25.d
@@ -0,0 +1,12 @@
+#name: sections 25 (.noinit)
+#target: [supports_noinit_section]
+#source: section25.s
+#readelf: -S --wide
+
+#...
+  \[..\] .noinit[ 	]+NOBITS[ 	]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00  WA .*
+#...
+  \[..\] .noinit.foo[ 	]+NOBITS[ 	]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00  WA .*
+#...
+  \[..\] .gnu.linkonce.n.bar[ 	]+NOBITS[ 	]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00  WA .*
+#pass
diff --git a/gas/testsuite/gas/elf/section25.s b/gas/testsuite/gas/elf/section25.s
new file mode 100644
index 0000000000..538e5c7ce4
--- /dev/null
+++ b/gas/testsuite/gas/elf/section25.s
@@ -0,0 +1,8 @@
+.section .noinit
+.word 0
+
+.section .noinit.foo
+.word 0
+
+.section .gnu.linkonce.n.bar
+.word 0
diff --git a/gas/testsuite/gas/elf/section26.d b/gas/testsuite/gas/elf/section26.d
new file mode 100644
index 0000000000..15d85bdca9
--- /dev/null
+++ b/gas/testsuite/gas/elf/section26.d
@@ -0,0 +1,12 @@
+#name: sections 26 (.persistent)
+#target: [supports_persistent_section]
+#source: section26.s
+#readelf: -S --wide
+
+#...
+  \[..\] .persistent[ 	]+PROGBITS[ 	]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00  WA .*
+#...
+  \[..\] .persistent.foo[ 	]+PROGBITS[ 	]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00  WA .*
+#...
+  \[..\] .gnu.linkonce.p.bar[ 	]+PROGBITS[ 	]+[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00  WA .*
+#pass
diff --git a/gas/testsuite/gas/elf/section26.s b/gas/testsuite/gas/elf/section26.s
new file mode 100644
index 0000000000..7f98645422
--- /dev/null
+++ b/gas/testsuite/gas/elf/section26.s
@@ -0,0 +1,8 @@
+.section .persistent
+.word 0
+
+.section .persistent.foo
+.word 0
+
+.section .gnu.linkonce.p.bar
+.word 0
diff --git a/ld/emulparams/armelf.sh b/ld/emulparams/armelf.sh
index 24ca8ed59d..1995c44997 100644
--- a/ld/emulparams/armelf.sh
+++ b/ld/emulparams/armelf.sh
@@ -10,19 +10,7 @@ OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)'
 OTHER_BSS_SYMBOLS="${CREATE_SHLIB+PROVIDE (}__bss_start__ = .${CREATE_SHLIB+)};"
 OTHER_BSS_END_SYMBOLS="${CREATE_SHLIB+PROVIDE (}_bss_end__ = .${CREATE_SHLIB+)}; ${CREATE_SHLIB+PROVIDE (}__bss_end__ = .${CREATE_SHLIB+)};"
 OTHER_END_SYMBOLS="${CREATE_SHLIB+PROVIDE (}__end__ = .${CREATE_SHLIB+)};"
-OTHER_SECTIONS='
-.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
-/* This section contains data that is not initialised during load
-   *or* application reset.  */
- .noinit (NOLOAD) :
- {
-   . = ALIGN(2);
-   PROVIDE (__noinit_start = .);
-   *(.noinit)
-   . = ALIGN(2);
-   PROVIDE (__noinit_end = .);
- }
-'
+OTHER_SECTIONS='.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }'
 ATTRS_SECTIONS='.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }'
 OTHER_READONLY_SECTIONS="
   .ARM.extab ${RELOCATING-0} : { *(.ARM.extab${RELOCATING+* .gnu.linkonce.armextab.*}) }
@@ -49,3 +37,7 @@ STACK_ADDR=0x80000
 
 # ARM does not support .s* sections.
 NO_SMALL_DATA=yes
+
+# ARM supports the .noinit and .persistent sections.
+HAVE_NOINIT=yes
+HAVE_PERSISTENT=yes
diff --git a/ld/scripttempl/avr.sc b/ld/scripttempl/avr.sc
index b85748b2f9..77238d6fd6 100644
--- a/ld/scripttempl/avr.sc
+++ b/ld/scripttempl/avr.sc
@@ -271,7 +271,7 @@ cat <<EOF
   .noinit ${RELOCATING+ ADDR(.bss) + SIZEOF (.bss)} ${RELOCATING-0}: ${RELOCATING+ AT (ADDR (.noinit))}
   {
     ${RELOCATING+ PROVIDE (__noinit_start = .) ; }
-    *(.noinit*)
+    *(.noinit${RELOCATING+ .noinit.* .gnu.linkonce.n.*})
     ${RELOCATING+ PROVIDE (__noinit_end = .) ; }
     ${RELOCATING+ _end = . ;  }
     ${RELOCATING+ PROVIDE (__heap_start = .) ; }
diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc
index eb74743e5c..d9e63e7b4c 100644
--- a/ld/scripttempl/elf.sc
+++ b/ld/scripttempl/elf.sc
@@ -8,6 +8,8 @@
 #	NOP - four byte opcode for no-op (defaults to none)
 #	NO_SMALL_DATA - no .sbss/.sbss2/.sdata/.sdata2 sections if not
 #		empty.
+#	HAVE_NOINIT - Include a .noinit output section in the script.
+#	HAVE_PERSISTENT - Include a .persistent output section in the script.
 #	SMALL_DATA_CTOR - .ctors contains small data.
 #	SMALL_DATA_DTOR - .dtors contains small data.
 #	DATA_ADDR - if end-of-text-plus-one-page isn't right for data start
@@ -103,6 +105,8 @@
 #  .lrodata	.gnu.linkonce.lr.foo
 #  .ldata	.gnu.linkonce.l.foo
 #  .lbss	.gnu.linkonce.lb.foo
+#  .noinit	.gnu.linkonce.n.foo
+#  .persistent	.gnu.linkonce.p.foo
 #
 #  Each of these can also have corresponding .rel.* and .rela.* sections.
 
@@ -322,6 +326,28 @@ STACK=".stack        ${RELOCATING-0}${RELOCATING+${STACK_ADDR}} :
     *(.stack)
     ${RELOCATING+${STACK_SENTINEL}}
   }"
+test "${HAVE_NOINIT}" = "yes" && NOINIT="
+  /* This section contains data that is not initialized during load,
+     or during the application's initialization sequence.  */
+  .noinit (NOLOAD) :
+  {
+    ${RELOCATING+. = ALIGN(${ALIGNMENT});}
+    ${RELOCATING+PROVIDE (__noinit_start = .);}
+    *(.noinit${RELOCATING+ .noinit.* .gnu.linkonce.n.*})
+    ${RELOCATING+. = ALIGN(${ALIGNMENT});}
+    ${RELOCATING+PROVIDE (__noinit_end = .);}
+  }"
+test "${HAVE_PERSISTENT}" = "yes" && PERSISTENT="
+  /* This section contains data that is initialized during load,
+     but not during the application's initialization sequence.  */
+  .persistent :
+  {
+    ${RELOCATING+. = ALIGN(${ALIGNMENT});}
+    ${RELOCATING+PROVIDE (__persistent_start = .);}
+    *(.persistent${RELOCATING+ .persistent.* .gnu.linkonce.p.*})
+    ${RELOCATING+. = ALIGN(${ALIGNMENT});}
+    ${RELOCATING+PROVIDE (__persistent_end = .);}
+  }"
 
 TEXT_START_ADDR="SEGMENT_START(\"text-segment\", ${TEXT_START_ADDR})"
 SHLIB_TEXT_START_ADDR="SEGMENT_START(\"text-segment\", ${SHLIB_TEXT_START_ADDR:-0})"
@@ -645,6 +671,7 @@ cat <<EOF
   ${DATA_SDATA-${SDATA}}
   ${DATA_SDATA-${OTHER_SDATA_SECTIONS}}
   ${RELOCATING+${DATA_END_SYMBOLS-${CREATE_SHLIB+PROVIDE (}${USER_LABEL_PREFIX}_edata = .${CREATE_SHLIB+)}; PROVIDE (${USER_LABEL_PREFIX}edata = .);}}
+  ${PERSISTENT}
   ${RELOCATING+. = .;}
   ${RELOCATING+${CREATE_SHLIB+PROVIDE (}${USER_LABEL_PREFIX}__bss_start = .${CREATE_SHLIB+)};}
   ${RELOCATING+${OTHER_BSS_SYMBOLS}}
@@ -665,6 +692,7 @@ cat <<EOF
   ${OTHER_BSS_SECTIONS}
   ${LARGE_BSS_AFTER_BSS+${LARGE_BSS}}
   ${RELOCATING+${OTHER_BSS_END_SYMBOLS}}
+  ${NOINIT}
   ${RELOCATING+. = ALIGN(${ALIGNMENT});}
 EOF
 
diff --git a/ld/scripttempl/elf32msp430.sc b/ld/scripttempl/elf32msp430.sc
index 4206d797b8..fafd775718 100644
--- a/ld/scripttempl/elf32msp430.sc
+++ b/ld/scripttempl/elf32msp430.sc
@@ -302,17 +302,25 @@ SECTIONS
   } ${RELOCATING+ > data}
   ${RELOCATING+ PROVIDE (__bsssize = SIZEOF(.bss)); }
 
+  /* This section contains data that is not initialized during load,
+     or during the application's initialization sequence.  */
   .noinit ${RELOCATING-0}${RELOCATING+SIZEOF(.bss) + ADDR(.bss)} :
   {
+    ${RELOCATING+. = ALIGN(2);}
     ${RELOCATING+ PROVIDE (__noinit_start = .) ; }
-    *(.noinit)
+    *(.noinit${RELOCATING+ .noinit.* .gnu.linkonce.n.*})
+    ${RELOCATING+. = ALIGN(2);}
     ${RELOCATING+ PROVIDE (__noinit_end = .) ; }
   } ${RELOCATING+ > data}
 
+  /* This section contains data that is initialized during load,
+     but not during the application's initialization sequence.  */
   .persistent ${RELOCATING-0}${RELOCATING+SIZEOF(.noinit) + ADDR(.noinit)} :
   {
+    ${RELOCATING+. = ALIGN(2);}
     ${RELOCATING+ PROVIDE (__persistent_start = .) ; }
-    *(.persistent)
+    *(.persistent${RELOCATING+ .persistent.* .gnu.linkonce.p.*})
+    ${RELOCATING+. = ALIGN(2);}
     ${RELOCATING+ PROVIDE (__persistent_end = .) ; }
   } ${RELOCATING+ > data}
 
diff --git a/ld/scripttempl/elfarcv2.sc b/ld/scripttempl/elfarcv2.sc
index b6cab6c580..a0c4f7ef76 100644
--- a/ld/scripttempl/elfarcv2.sc
+++ b/ld/scripttempl/elfarcv2.sc
@@ -283,7 +283,7 @@ SECTIONS
   /* Global data not cleared after reset.  */
   .noinit ${RELOCATING-0}:
   {
-    *(.noinit*)
+    *(.noinit${RELOCATING+ .noinit.* .gnu.linkonce.n.*})
     ${RELOCATING+. = ALIGN(${ALIGNMENT});}
     ${RELOCATING+ PROVIDE (__start_heap = .) ; }
   } ${RELOCATING+ > ${DATA_MEMORY}}
diff --git a/ld/scripttempl/pru.sc b/ld/scripttempl/pru.sc
index 9ef798082f..08aceaa3b2 100644
--- a/ld/scripttempl/pru.sc
+++ b/ld/scripttempl/pru.sc
@@ -167,7 +167,7 @@ SECTIONS
   .noinit ${RELOCATING-0} :
   {
     ${RELOCATING+ PROVIDE (_noinit_start = .) ; }
-    *(.noinit)
+    *(.noinit${RELOCATING+ .noinit.* .gnu.linkonce.n.*})
     ${RELOCATING+ PROVIDE (_noinit_end = .) ; }
     ${RELOCATING+ PROVIDE (_heap_start = .) ; }
     ${RELOCATING+ . += __HEAP_SIZE ; }
diff --git a/ld/testsuite/ld-elf/noinit-sections-1.d b/ld/testsuite/ld-elf/noinit-sections-1.d
new file mode 100644
index 0000000000..133205cce8
--- /dev/null
+++ b/ld/testsuite/ld-elf/noinit-sections-1.d
@@ -0,0 +1,9 @@
+#name: .noinit sections
+#ld: --orphan-handling=warn -e _start
+#source: noinit-sections.s
+#target: [supports_noinit_section]
+#readelf: -SW
+
+#...
+ +\[ *[0-9]+\] \.noinit +NOBITS +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +00 +WA .*
+#pass
diff --git a/ld/testsuite/ld-elf/noinit-sections-2.d b/ld/testsuite/ld-elf/noinit-sections-2.d
new file mode 100644
index 0000000000..f3eb4e50fb
--- /dev/null
+++ b/ld/testsuite/ld-elf/noinit-sections-2.d
@@ -0,0 +1,10 @@
+#name: .noinit sections (ld -r)
+#ld: --orphan-handling=warn -e _start -r
+#source: noinit-sections.s
+#target: [supports_noinit_section]
+#readelf: -SW
+#warning_output: noinit-sections-2.l
+
+#...
+ +\[ *[0-9]+\] \.noinit +NOBITS +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +00 +WA .*
+#pass
diff --git a/ld/testsuite/ld-elf/noinit-sections-2.l b/ld/testsuite/ld-elf/noinit-sections-2.l
new file mode 100644
index 0000000000..0784c9e3e1
--- /dev/null
+++ b/ld/testsuite/ld-elf/noinit-sections-2.l
@@ -0,0 +1,5 @@
+#...
+[^:]*: warning: orphan section `.noinit.var_noinit' from \S+ being placed in section `.noinit.var_noinit'
+#...
+[^:]*: warning: orphan section `.gnu.linkonce.n.var_noinit2' from \S+ being placed in section `.gnu.linkonce.n.var_noinit2'
+#pass
diff --git a/ld/testsuite/ld-elf/noinit-sections.s b/ld/testsuite/ld-elf/noinit-sections.s
new file mode 100644
index 0000000000..f840bb0fb3
--- /dev/null
+++ b/ld/testsuite/ld-elf/noinit-sections.s
@@ -0,0 +1,13 @@
+.section	.noinit,"aw",%nobits
+.word 0
+
+.section	.noinit.var_noinit,"aw",%nobits
+.word 0
+
+.section	.gnu.linkonce.n.var_noinit2,"aw",%nobits
+.word 0
+
+.text
+.global _start
+_start:
+.word 0
diff --git a/ld/testsuite/ld-elf/persistent-sections-1.d b/ld/testsuite/ld-elf/persistent-sections-1.d
new file mode 100644
index 0000000000..5815cfa11b
--- /dev/null
+++ b/ld/testsuite/ld-elf/persistent-sections-1.d
@@ -0,0 +1,9 @@
+#name: .persistent sections
+#ld: --orphan-handling=warn -e _start
+#source: persistent-sections.s
+#target: [supports_persistent_section]
+#readelf: -SW
+
+#...
+ +\[ *[0-9]+\] \.persistent +PROGBITS +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +00 +WA .*
+#pass
diff --git a/ld/testsuite/ld-elf/persistent-sections-2.d b/ld/testsuite/ld-elf/persistent-sections-2.d
new file mode 100644
index 0000000000..3778514a8d
--- /dev/null
+++ b/ld/testsuite/ld-elf/persistent-sections-2.d
@@ -0,0 +1,10 @@
+#name: .persistent sections (ld -r)
+#ld: --orphan-handling=warn -e _start -r
+#source: persistent-sections.s
+#target: [supports_persistent_section]
+#readelf: -SW
+#warning_output: persistent-sections-2.l
+
+#...
+ +\[ *[0-9]+\] \.persistent +PROGBITS +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +00 +WA .*
+#pass
diff --git a/ld/testsuite/ld-elf/persistent-sections-2.l b/ld/testsuite/ld-elf/persistent-sections-2.l
new file mode 100644
index 0000000000..a5bbe4b04f
--- /dev/null
+++ b/ld/testsuite/ld-elf/persistent-sections-2.l
@@ -0,0 +1,5 @@
+#...
+[^:]*: warning: orphan section `.persistent.var_persistent' from \S+ being placed in section `.persistent.var_persistent'
+#...
+[^:]*: warning: orphan section `.gnu.linkonce.p.var_persistent2' from \S+ being placed in section `.gnu.linkonce.p.var_persistent2'
+#pass
diff --git a/ld/testsuite/ld-elf/persistent-sections.s b/ld/testsuite/ld-elf/persistent-sections.s
new file mode 100644
index 0000000000..04f6155d98
--- /dev/null
+++ b/ld/testsuite/ld-elf/persistent-sections.s
@@ -0,0 +1,13 @@
+.section	.persistent,"aw"
+.word 1
+
+.section	.persistent.var_persistent,"aw"
+.word 2
+
+.section	.gnu.linkonce.p.var_persistent2,"aw"
+.word 3
+
+.text
+.global _start
+_start:
+.word 0
-- 
2.29.2



More information about the Binutils mailing list