[V2,0/3] Fix "noinit" attr, implement "persistent" attr

Message ID 20201115220252.52ps4tgdsejnzh4w@jozef-acer-manjaro
State New
Headers show

Commit Message

Jozef Lawrynowicz Nov. 15, 2020, 10:02 p.m.
This patch series is version 2 of
https://gcc.gnu.org/pipermail/gcc-patches/2020-October/557184.html

The implementation is now simplified so as to not use a symtab flag for
"noinit" variables, instead we just check whether the decl has the
attribute set.

 This patch series fixes behavior related to the "noinit" attribute, and
 makes the MSP430 "persistent" attribute generic, so it can be used for
 ARM.
 These attributes are related because they are both used to mark
 variables that should not be initialized by the target's runtime
 startup code.

 The "noinit" attribute is used for variables that are not initialized
 to any value by the program loader, or the runtime startup code.
 This attribute was made generic for GCC 10, whilst previously it was
 only supported for MSP430.
 There are a couple of issues when using it for arm-eabi:
 - It does not work at -O0.
   The test for it is in the torture directory but only runs at -O2,
   which is why this bug was undetected.
 - It does not work with -fdata-sections.
 Patch 1 fixes these issues.

 The "persistent" attribute is used for variables that *are* initialized
 by the program loader, but are not initialized by the runtime startup
 code. "persistent" variables are placed in a non-volatile area of
 memory, which allows their value to "persist" between processor resets.

 The "persistent" attribute is already implemented for msp430-elf, but
 patch 3 makes it generic so it can be leveraged by ARM targets. The
 ".persistent" section is pervasive in linker scripts distributed for
 ARM devices by manufacturers such as ST and TI.
 Patch 2 enables validation of the "persistent" attribute for when
 compiling C++ programs.

 I've attached a Binutils patch that adds the ".persistent" section to
 the default ARM linker script. I'll apply it alongside this GCC patch.

 Side note: There is handling of a ".persistent.bss" section, however
 this is Ada-specific and unrelated to the "noinit" and "persistent"
 attributes. The handling of the "noinit" and "persistent" attributes
 does not interfere with it.

msp430-elf "persistent" attribute behaviour needs changing if this patch
is approved, I have a patch ready to do that.

Successfully regtested for arm-none-eabi.

Ok for trunk?

Jozef Lawrynowicz (3):
  Fix "noinit" attribute being ignored for -O0 and -fdata-sections
  cp/decl.c: Set DECL_INITIAL before attribute processing
  Implement the "persistent" attribute

 gcc/c-family/c-attribs.c                      | 141 ++++++++++++------
 gcc/cp/decl.c                                 |  13 ++
 gcc/doc/extend.texi                           |  20 ++-
 .../c-c++-common/torture/attr-noinit-1.c      |   7 +
 .../c-c++-common/torture/attr-noinit-2.c      |   8 +
 .../c-c++-common/torture/attr-noinit-3.c      |  11 ++
 .../torture/attr-noinit-invalid.c             |  12 ++
 .../torture/attr-noinit-main.inc}             |  37 ++---
 .../c-c++-common/torture/attr-persistent-1.c  |   8 +
 .../c-c++-common/torture/attr-persistent-2.c  |   8 +
 .../c-c++-common/torture/attr-persistent-3.c  |  10 ++
 .../torture/attr-persistent-invalid.c         |  11 ++
 .../torture/attr-persistent-main.inc          |  58 +++++++
 .../g++.target/msp430/data-attributes.C       |  52 +++++++
 gcc/testsuite/g++.target/msp430/msp430.exp    |  44 ++++++
 .../gcc.target/msp430/data-attributes-2.c     |   1 +
 gcc/testsuite/lib/target-supports.exp         |  15 +-
 gcc/tree.h                                    |  14 ++
 gcc/varasm.c                                  |  29 +++-
 19 files changed, 426 insertions(+), 73 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/torture/attr-noinit-1.c
 create mode 100644 gcc/testsuite/c-c++-common/torture/attr-noinit-2.c
 create mode 100644 gcc/testsuite/c-c++-common/torture/attr-noinit-3.c
 create mode 100644 gcc/testsuite/c-c++-common/torture/attr-noinit-invalid.c
 rename gcc/testsuite/{gcc.c-torture/execute/noinit-attribute.c => c-c++-common/torture/attr-noinit-main.inc} (56%)
 create mode 100644 gcc/testsuite/c-c++-common/torture/attr-persistent-1.c
 create mode 100644 gcc/testsuite/c-c++-common/torture/attr-persistent-2.c
 create mode 100644 gcc/testsuite/c-c++-common/torture/attr-persistent-3.c
 create mode 100644 gcc/testsuite/c-c++-common/torture/attr-persistent-invalid.c
 create mode 100644 gcc/testsuite/c-c++-common/torture/attr-persistent-main.inc
 create mode 100644 gcc/testsuite/g++.target/msp430/data-attributes.C
 create mode 100644 gcc/testsuite/g++.target/msp430/msp430.exp

-- 
2.29.2
From 870479a3d2e7dc07441df07b4b8947d111ffb2f9 Mon Sep 17 00:00:00 2001
From: Jozef Lawrynowicz <jozef.l@mittosystems.com>

Date: Mon, 26 Oct 2020 17:55:16 +0000
Subject: [PATCH] support .noinit and .persistent in arm linker script

---
 ld/emulparams/armelf.sh                 | 16 +++++++++++++---
 ld/testsuite/ld-elf/noinit-sections-1.d | 11 +++++++++++
 ld/testsuite/ld-elf/noinit-sections-2.d | 12 ++++++++++++
 ld/testsuite/ld-elf/noinit-sections-2.l |  5 +++++
 ld/testsuite/ld-elf/noinit-sections.s   | 16 ++++++++++++++++
 5 files changed, 57 insertions(+), 3 deletions(-)
 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

-- 
2.28.0

Patch

diff --git a/ld/emulparams/armelf.sh b/ld/emulparams/armelf.sh
index 24ca8ed59d..f9ccc499cc 100644
--- a/ld/emulparams/armelf.sh
+++ b/ld/emulparams/armelf.sh
@@ -10,7 +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='
+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.  */
@@ -18,11 +18,21 @@  OTHER_SECTIONS='
  {
    . = ALIGN(2);
    PROVIDE (__noinit_start = .);
-   *(.noinit)
+   *(.noinit${RELOCATING+ .noinit.* .gnu.linkonce.n.*})
    . = ALIGN(2);
    PROVIDE (__noinit_end = .);
  }
-'
+/* This section contains data that *is* initialized during load,
+   but *not* during application reset.  */
+ .persistent :
+ {
+   . = ALIGN(2);
+   PROVIDE (__persistent_start = .);
+   *(.persistent${RELOCATING+ .persistent.* .gnu.linkonce.p.*})
+   . = ALIGN(2);
+   PROVIDE (__persistent_end = .);
+ }
+"
 ATTRS_SECTIONS='.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }'
 OTHER_READONLY_SECTIONS="
   .ARM.extab ${RELOCATING-0} : { *(.ARM.extab${RELOCATING+* .gnu.linkonce.armextab.*}) }
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..7e35cd2a82
--- /dev/null
+++ b/ld/testsuite/ld-elf/noinit-sections-1.d
@@ -0,0 +1,11 @@ 
+#name: .noinit and .persistent sections
+#ld: --orphan-handling=warn -e _start
+#source: noinit-sections.s
+#target: arm-*-* msp430-*-elf
+#readelf: -SW
+
+#...
+ +\[ *[0-9]+\] \.noinit +NOBITS +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +00 +WA .*
+#...
+ +\[ *[0-9]+\] \.persistent +PROGBITS +[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..190c46fcf3
--- /dev/null
+++ b/ld/testsuite/ld-elf/noinit-sections-2.d
@@ -0,0 +1,12 @@ 
+#name: .noinit and .persistent sections (ld -r)
+#ld: --orphan-handling=warn -e _start -r
+#source: noinit-sections.s
+#target: arm-*-* msp430-*-elf
+#readelf: -SW
+#warning_output: noinit-sections-2.l
+
+#...
+ +\[ *[0-9]+\] \.noinit +NOBITS +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +00 +WA .*
+#...
+ +\[ *[0-9]+\] \.persistent +PROGBITS +[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..41ce6de01c
--- /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 `.persistent.var_persistent' from \S+ being placed in section `.persistent.var_persistent'
+#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..793f71769e
--- /dev/null
+++ b/ld/testsuite/ld-elf/noinit-sections.s
@@ -0,0 +1,16 @@ 
+.section	.noinit,"aw",%nobits
+.word 0
+
+.section	.noinit.var_noinit,"aw",%nobits
+.word 0
+
+.section	.persistent,"aw"
+.word 1
+
+.section	.persistent.var_persistent,"aw"
+.word 2
+
+.text
+.global _start
+_start:
+.word 0