From patchwork Thu Jul 4 15:27:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Lyon X-Patchwork-Id: 168474 Delivered-To: patch@linaro.org Received: by 2002:a92:4782:0:0:0:0:0 with SMTP id e2csp2414192ilk; Thu, 4 Jul 2019 08:27:59 -0700 (PDT) X-Google-Smtp-Source: APXvYqyEejvLfbiw7e53MWjn0oREubldB/y9uHvgrXOfsY4lo3PG7NW4yffK2APLt6e6MCKUlrND X-Received: by 2002:a17:90a:fa18:: with SMTP id cm24mr152325pjb.120.1562254079064; Thu, 04 Jul 2019 08:27:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1562254079; cv=none; d=google.com; s=arc-20160816; b=E0evFkMh1F8mPjvdoaM9H8cVdK6ZmHppuXYr38oJwQhNMtfSbelJmjZCIc2NpwZCQi NGqP76rr0wIiwcupOuA7Q1zzKwo0qV/U2CakFlM+5bCToETYK3z/YpPf/OJD1Xk1yRal JveVGFCLCVW/0ivpIycy3YdT6aikgKBVW6NhASQy/PNZpNUeIkmuzUGd08UvS7hwakzD M6j6/bSXYdLzd+qmKN/fHr3ZzLSX+g8iZvc+Cxad7SMN/+Q+3uF7jOnHi0RZNhGx1fNz Lp68NDyjdDs9riLO5HPS4uOxmrqYWErjXLLrVrxOyDhm/KIeYawmsWnimZhN6Ln2UWyM oQxQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:subject:message-id:date:from:mime-version:dkim-signature :delivered-to:sender:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature; bh=QSYz5yaLnaHU0/FeIL4oYQ+VpDwAi5YwVLx9C1A/Wec=; b=WFyHla0Pa/p8rOgin5rrd/W3QBGTAwhXyKTobm9FnNvhRR4EDZeGEjmqMRPkIx3b1c o41UEWpehlBQ+TB64C16GeuTCZUeZtkkXpyvwa2ZgQW+XA6N5x330gzQk7i+wwmRzofg 3cJD7MeElXhkJaMCDdky40dPbA3dKY9E6ms8FJJhDwq7Lk4F1FB2myomi+v59zSNOYAT 3Oavgs973rcrDvZR/s7D4LqOsm7x91utRbxt0JZhs5s6+K3bF8FekXVzKdNJ/8lwu+GI ZBEsOwUDAUBj5rjBq/JkIooRGs8nIwjZZ+okgXhVpIxsVFw3U88FCSWh3NIPKiU1AFlx I1qA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=mgZBTxms; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=q0ntUE9o; spf=pass (google.com: domain of gcc-patches-return-504414-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="gcc-patches-return-504414-patch=linaro.org@gcc.gnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id a20si5614042pgw.306.2019.07.04.08.27.58 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 04 Jul 2019 08:27:59 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-504414-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=mgZBTxms; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=q0ntUE9o; spf=pass (google.com: domain of gcc-patches-return-504414-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="gcc-patches-return-504414-patch=linaro.org@gcc.gnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; q= dns; s=default; b=wcYvc1rNIX2eiXEHTWm+ama+HUx0u2/g5ej0Gquo520jzF wp9lgTmSuLQLBcRy6yhIZ0D6qS31BOnAIdeLnV6OhdQT7pgi6CYmSviF4a6oPBSZ gvrD6H5uhrWIZgFa8Z1addZgBVNJIlUzAooOno7fN9iYxmGvT5SDMAuvDYNqA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; s= default; bh=L9PSsnPUVXYeoD3fmcuMSgWD+UM=; b=mgZBTxmsapSdBOgUZUuL jbpCZiBsIYe9fTF5fEdfXd2E4UNpgHJBTju2hfqScd0ESE3EDB8uvJ6NeTfDHX/l AnCoE5MRZRtu36KYZPTj4uXPzlAYxFPjjOyMpcpyIJXZU2JoPRoFKlhsMhDRUbrq E4RDxbyXvDYVgTZeFf6+u9M= Received: (qmail 19733 invoked by alias); 4 Jul 2019 15:27:46 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 19725 invoked by uid 89); 4 Jul 2019 15:27:46 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-15.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=PROVIDE, embedded X-HELO: mail-lj1-f171.google.com Received: from mail-lj1-f171.google.com (HELO mail-lj1-f171.google.com) (209.85.208.171) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 04 Jul 2019 15:27:42 +0000 Received: by mail-lj1-f171.google.com with SMTP id h10so6560569ljg.0 for ; Thu, 04 Jul 2019 08:27:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:from:date:message-id:subject:to; bh=B1gKBywUAZnonEK4/AhKXdE3zKE/IPq8F6/4HU8cTKw=; b=q0ntUE9o/SQFMG2wF46m3EEEdf59oOb7BQXjYU0pZmIMKxEd6e5l/370rgLGknw8DA H/GjntJTvrXI5fSg5lmSeiq0iaGnFY0U9qkx3nXHiP9/CanNAS2SRYt/iP2x3r7Z4Q90 aLAzhcu1v/O4crXlE5DmUnthaXqPlJUnhYf1i7zgs/tx9AQ5mmubmfV8gFus4DEmprz1 vnyIQzSXaTxgbCixUKWAJRD6FO8crOiDx09I6LUPWBT+Me0i0y+eBz+UuTTKQOlnpTI5 Go1nyBCuTUrYRCVAaQUNnhSvEc41yrIWqIWPEM/wlImTCmk6730PROdLrfZ0fDyv1FGg uJDQ== MIME-Version: 1.0 From: Christophe Lyon Date: Thu, 4 Jul 2019 17:27:28 +0200 Message-ID: Subject: [PATCH] Add generic support for "noinit" attribute To: gcc Patches , Richard Earnshaw , nick clifton X-IsSubscribed: yes Hi, Similar to what already exists for TI msp430 or in TI compilers for arm, this patch adds support for the "noinit" attribute. It is convenient for embedded targets where the user wants to keep the value of some data when the program is restarted: such variables are not zero-initialized. It is mostly a helper/shortcut to placing variables in a dedicated section. It's probably desirable to add the following chunk to the GNU linker: + } +' so that the noinit section has the "NOLOAD" flag. I'll submit that part separately to the binutils project if OK. However, I'm not sure for which other targets (beyond arm), I should update the linker scripts. I left the new testcase in gcc.target/arm, guarded by dg-do run { target { *-*-eabi } } but since this attribute is now generic, I suspect I should move the test to some other place. But then, which target selector should I use? Finally, I tested on arm-eabi, but not on msp430 for which I do not have the environment, so advice from msp430 maintainers is appreciated. Since msp430 does not use the same default helpers as arm, I left the "noinit" handling code in place, to avoid changing other generic functions which I don't know how to test (default_select_section, default_section_type_flags). Thanks, Christophe gcc/ChangeLog: 2019-07-04 Christophe Lyon * doc/extend.texi: Add "noinit" attribute documentation. * varasm.c (default_section_type_flags): Add support for "noinit" section. (default_elf_select_section): Add support for "noinit" attribute. gcc/c-family/ChangeLog: 2019-07-04 Christophe Lyon * c-attribs.c (c_common_attribute_table): Add "noinit" entry. (handle_section_attribute): Add support for "noinit" attribute. (handle_noinit_attribute): New function. gcc/config/ChangeLog: 2019-07-04 Christophe Lyon * msp430/msp430.c (msp430_attribute_table): Remove "noinit" entry. gcc/testsuite/ChangeLog: 2019-07-04 Christophe Lyon * gcc.target/arm/noinit-attribute.c: New test. diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index 48819e7..3aefe84 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -92,6 +92,7 @@ static tree handle_section_attribute (tree *, tree, tree, int, bool *); static tree handle_aligned_attribute (tree *, tree, tree, int, bool *); static tree handle_warn_if_not_aligned_attribute (tree *, tree, tree, int, bool *); +static tree handle_noinit_attribute (tree *, tree, tree, int, bool *); static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ; static tree handle_noplt_attribute (tree *, tree, tree, int, bool *) ; static tree handle_alias_ifunc_attribute (bool, tree *, tree, tree, bool *); @@ -458,6 +459,8 @@ const struct attribute_spec c_common_attribute_table[] = handle_nocf_check_attribute, NULL }, { "copy", 1, 1, false, false, false, false, handle_copy_attribute, NULL }, + { "noinit", 0, 0, true, false, false, false, + handle_noinit_attribute, NULL }, { NULL, 0, 0, false, false, false, false, NULL, NULL } }; @@ -1912,6 +1915,13 @@ handle_section_attribute (tree *node, tree ARG_UNUSED (name), tree args, goto fail; } + if (DECL_P (decl) && lookup_attribute ("noinit", DECL_ATTRIBUTES (decl)) != NULL_TREE) + { + warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wattributes, + "section attribute cannot be applied to variables with noinit attribute"); + goto fail; + } + set_decl_section_name (decl, TREE_STRING_POINTER (TREE_VALUE (args))); return NULL_TREE; @@ -2224,6 +2234,48 @@ handle_weak_attribute (tree *node, tree name, return NULL_TREE; } +/* Handle a "noinit" attribute; arguments as in struct + attribute_spec.handler. Check whether the attribute is allowed here + and add the attribute to the variable decl tree or otherwise issue + a diagnostic. This function checks NODE is of the expected type and + issues diagnostics otherwise using NAME. If it is not of the + expected type *NO_ADD_ATTRS will be set to true. */ + +static tree +handle_noinit_attribute (tree * node, + tree name, + tree args, + int flags ATTRIBUTE_UNUSED, + bool * no_add_attrs) +{ + const char * message = NULL; + + gcc_assert (DECL_P (*node)); + gcc_assert (args == NULL); + + if (TREE_CODE (* node) != VAR_DECL) + message = G_("%qE attribute only applies to variables"); + + /* Check that it's possible for the variable to have a section. */ + if ((TREE_STATIC (* node) || DECL_EXTERNAL (* node) || in_lto_p) + && DECL_SECTION_NAME (* node)) + message = G_("%qE attribute cannot be applied to variables with specific sections"); + + /* If this var is thought to be common, then change this. Common variables + are assigned to sections before the backend has a chance to process them. */ + if (DECL_COMMON (* node)) + DECL_COMMON (* node) = 0; + + if (message) + { + warning (OPT_Wattributes, message, name); + * no_add_attrs = true; + } + + return NULL_TREE; +} + + /* Handle a "noplt" attribute; arguments as in struct attribute_spec.handler. */ diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index 365e9eb..8266fa0 100644 --- a/gcc/config/msp430/msp430.c +++ b/gcc/config/msp430/msp430.c @@ -1807,7 +1807,6 @@ const char * const ATTR_CRIT = "critical"; const char * const ATTR_LOWER = "lower"; const char * const ATTR_UPPER = "upper"; const char * const ATTR_EITHER = "either"; -const char * const ATTR_NOINIT = "noinit"; const char * const ATTR_PERSIST = "persistent"; static inline bool @@ -2108,8 +2107,6 @@ const struct attribute_spec msp430_attribute_table[] = { ATTR_EITHER, 0, 0, true, false, false, false, msp430_section_attr, NULL }, - { ATTR_NOINIT, 0, 0, true, false, false, false, msp430_data_attr, - NULL }, { ATTR_PERSIST, 0, 0, true, false, false, false, msp430_data_attr, NULL }, diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index f2619e1..850153e 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -7129,6 +7129,12 @@ The @code{visibility} attribute is described in The @code{weak} attribute is described in @ref{Common Function Attributes}. +@item noinit +@cindex @code{noinit} variable attribute +Any data with the @code{noinit} attribute will not be initialized by +the C runtime startup code, or the program loader. Not initializing +data in this way can reduce program startup times. + @end table @node ARC Variable Attributes diff --git a/gcc/testsuite/gcc.target/arm/noinit-attribute.c b/gcc/testsuite/gcc.target/arm/noinit-attribute.c new file mode 100644 index 0000000..242de2f --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/noinit-attribute.c @@ -0,0 +1,56 @@ +/* { dg-do run { target { *-*-eabi } } } */ +/* { dg-options "-O2" } */ + +/* This test checks that noinit data is handled correctly. */ + +extern void _start (void) __attribute__ ((noreturn)); +extern void abort (void) __attribute__ ((noreturn)); +extern void exit (int) __attribute__ ((noreturn)); + +int var_common; +int var_zero = 0; +int var_one = 1; +int __attribute__((noinit)) var_noinit; +int var_init = 2; + +int __attribute__((noinit)) func(); /* { dg-warning "attribute only applies to variables" } */ +int __attribute__((section ("mysection"), noinit)) var_section1; /* { dg-warning "attribute cannot be applied to variables with specific sections" } */ +int __attribute__((noinit, section ("mysection"))) var_section2; /* { dg-warning "attribute cannot be applied to variables with noinit attribute" } */ + + +int +main (void) +{ + /* Make sure that the C startup code has correctly initialised the ordinary variables. */ + if (var_common != 0) + abort (); + + /* Initialised variables are not re-initialised during startup, so check their original values only during the first run of this test. */ + if (var_init == 2) + if (var_zero != 0 || var_one != 1) + abort (); + + switch (var_init) + { + case 2: + /* First time through - change all the values. */ + var_common = var_zero = var_one = var_noinit = var_init = 3; + break; + + case 3: + /* Second time through - make sure that d has not been reset. */ + if (var_noinit != 3) + abort (); + exit (0); + + default: + /* Any other value for var_init is an error. */ + abort (); + } + + /* Simulate a processor reset by calling the C startup code. */ + _start (); + + /* Should never reach here. */ + abort (); +} diff --git a/gcc/varasm.c b/gcc/varasm.c index 626a4c9..d013486 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -6428,6 +6428,9 @@ default_section_type_flags (tree decl, const char *name, int reloc) || strncmp (name, ".gnu.linkonce.tb.", 17) == 0) flags |= SECTION_TLS | SECTION_BSS; + if (strcmp (name, ".noinit") == 0) + flags |= SECTION_WRITE | SECTION_BSS | SECTION_NOTYPE; + /* Various sections have special ELF types that the assembler will assign by default based on the name. They are neither SHT_PROGBITS nor SHT_NOBITS, so when changing sections we don't want to print a @@ -6748,11 +6751,14 @@ decl_readonly_section (const_tree decl, int reloc) /* Select a section based on the above categorization. */ +static section *noinit_section = NULL; + section * default_elf_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align) { const char *sname; + switch (categorize_decl_for_section (decl, reloc)) { case SECCAT_TEXT: @@ -6790,6 +6796,13 @@ default_elf_select_section (tree decl, int reloc, sname = ".tdata"; break; case SECCAT_BSS: + if (DECL_P (decl) && lookup_attribute ("noinit", DECL_ATTRIBUTES (decl)) != NULL_TREE) + { + if (noinit_section == NULL) + noinit_section = get_named_section (decl, ".noinit", reloc); + return noinit_section; + } + if (bss_section) return bss_section; sname = ".bss"; diff --git a/ld/emulparams/armelf.sh b/ld/emulparams/armelf.sh index 272a8bc..9555cec 100644 --- a/ld/emulparams/armelf.sh +++ b/ld/emulparams/armelf.sh @@ -10,7 +10,19 @@ 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)) }' +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 = .);