From patchwork Thu Jun 13 15:13:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Lyon X-Patchwork-Id: 166681 Delivered-To: patch@linaro.org Received: by 2002:a92:4782:0:0:0:0:0 with SMTP id e2csp884757ilk; Thu, 13 Jun 2019 08:14:01 -0700 (PDT) X-Google-Smtp-Source: APXvYqxz5OKpXELd9ptg0UlCFMzmnD6iOo/P1u7CxUtrDBDKrMVUNZ4Rg3zx5Nzhy/J6hFiiHuS4 X-Received: by 2002:a62:b40a:: with SMTP id h10mr94760308pfn.216.1560438841176; Thu, 13 Jun 2019 08:14:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1560438841; cv=none; d=google.com; s=arc-20160816; b=KFKjMEWlLMLM3qZXG/UvsXHYmJjbs0bvZnvbIDZmpl+El9qklmO6OB5a86EEDlrot4 ewAXCSbv0b/fl4yh8bTs8HKtQ3P6Fc8W19W2Yix6/SEQmKN8R9HzpmR3v+LZ5rnWecr2 XXzEbVU8e1DZSlrLYh/hJo07WCCPffcamVIdyIkBThutc7fs5w/RQKAlwCCQfc7RYW1n xmNvdDYFnhYkhUAJjR8hVaKeWq6iL4MT1XYvmM0nq/zYcG1ELTBGT3csXxTzgDSDNdL1 GSnC0Xzpp5KJ1EBXkRkxxT8/aGWJbl2ZUTg5KvSUK2J17yA7e5k3sYJOIhrXNkvZ5Bzo 1PGQ== 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=AxpAuMPbuodlIdW8jP1VjK5QsbOTjQ+1Fl3fJMGuXcA=; b=VOjFzLzNy2479ERqtffCgXP0U2KUAajOTKqw1ZnMTFSdymk9GXjUCn1oyQQKQYixNY xEojYlKAmra+RJPeNa7nSAtUM0J8lWRDDXUty41K6K/TWsDGIkQBJ+k5I8Ti1bJSNUDx xqlxlf/93+V8d8e2F+2GEZar6Gb/mhwGCDubkOqLiZyuJwG0smWCdzY9TJLDsRToQQzt Qdp7BfFpDEd4smnB3QSl/LmCvFtQygC/Wq3Tdal5WGjvN6mOJpHDwjMyh+yK8bk0UgaH HT3rLOWSHxcYHhboYh+u12LPQrn/SyH55GgPb5qx3nSM26xEs+rQ2bshBizmLesAjWC2 WocA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=QmGx8cXS; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=inMdMjC3; spf=pass (google.com: domain of gcc-patches-return-502904-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="gcc-patches-return-502904-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 l1si64259pgi.278.2019.06.13.08.14.00 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 13 Jun 2019 08:14:01 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-502904-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=QmGx8cXS; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=inMdMjC3; spf=pass (google.com: domain of gcc-patches-return-502904-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="gcc-patches-return-502904-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=F/qJ4ge5wtnvf2Jq4Vh9dyuHqnCdcOh1glnvvys75gAiFH 1lF5LFVA0PQfkY2ZQGnDLCCeN/t6qjzIgz1fYANvvIu/k0wW9sxcYS2Ue/566nN8 dkpeoKAHRu17Bp8+i0fkQoJawNJ19r55M5KRmmdqpPXFm29Vm+VT64vuHP510= 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=AfRCHGL6iHqXVLoOmRwRYrRm6mM=; b=QmGx8cXSJsVUmrCRwr4d UerMFuEp6k9WIvJXh4j8w3qGMRKODeZq92dvF1/8KZFlAn5FVD35D245NRRiqs3Z N099t2NLjtwcImquoyYuT81EaQyfnQjEK1IzTj3CmUrFtv9+TM0y46n1I4Oaqob9 /507Q5KS2xS0RVyfP7VnBks= Received: (qmail 49170 invoked by alias); 13 Jun 2019 15:13:50 -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 49162 invoked by uid 89); 13 Jun 2019 15:13:50 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-15.4 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, christophe, Lyon, lyon X-HELO: mail-lj1-f177.google.com Received: from mail-lj1-f177.google.com (HELO mail-lj1-f177.google.com) (209.85.208.177) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 13 Jun 2019 15:13:47 +0000 Received: by mail-lj1-f177.google.com with SMTP id v24so14560325ljg.13 for ; Thu, 13 Jun 2019 08:13:47 -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=3v1AVJdY/ymMibb9qgYfcdwh6KZPoxnftVGcfm5zCmw=; b=inMdMjC3eig0bS9KhNxbP0RG6sPSeP0XPulAPOUBayaiZAUqL6bOi0hti0y7Z8vr6S 5QVj1YfXIVRsIt6a9VSa76uXv5kjat0bm6iTYOLGsyXdjeQuo8l2P2h1lNK/G25vglOi efwI8QFqGLgLxMf/Elr63aFpFBP+2wsljEWXEXTp3OjseN7MhC+s/xrOO9W6txuvOnD0 b51I68H56ePQwfSOOhx8JUF5a2WTAqfORQps5kWk6Gn1qVq0zlwRrh9tLeorO6P9mxWS 6yT2a2GFBmu3nSvWR/5TSLPiJeHsRYofyiCv2bksW7KNSJ2FhYCxXopOzOx3pWGylw4p wSYw== MIME-Version: 1.0 From: Christophe Lyon Date: Thu, 13 Jun 2019 17:13:34 +0200 Message-ID: Subject: [PATCH][ARM] Add support for "noinit" attribute To: gcc Patches X-IsSubscribed: yes Hi, Similar to what already exists for TI msp430 or in TI compilers for arm, this patch adds support for "noinit" attribute for arm. It's very similar to the corresponding code in GCC for msp430. It is useful 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. OK? Thanks, Christophe gcc/ChangeLog: 2019-06-13 Christophe Lyon * config/arm/arm.c (arm_attribute_table): Add "noinit" entry. (arm_data_attr): New helper function. (TARGET_ASM_SELECT_SECTION): New. (arm_select_section): New function. (arm_elf_section_type_flags): Add support for "noinit" section. * doc/extend.texi: Add "noinit" attribute documentation. gcc/testsuite/ChangeLog: 2019-06-13 Christophe Lyon * gcc.target/arm/data-attributes.c: New test. commit e04bcd361a87925ac8240bc106f64a37917bb804 Author: Christophe Lyon Date: Tue Jun 11 21:09:08 2019 +0000 Add support for noinit attribute. Change-Id: Ib7090c037f67e521ad9753e1a78ed5731996fefe diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index e3e71ea..332c41b 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -151,6 +151,7 @@ static tree arm_handle_notshared_attribute (tree *, tree, tree, int, bool *); #endif static tree arm_handle_cmse_nonsecure_entry (tree *, tree, tree, int, bool *); static tree arm_handle_cmse_nonsecure_call (tree *, tree, tree, int, bool *); +static tree arm_data_attr (tree *, tree, tree, int, bool *); static void arm_output_function_epilogue (FILE *); static void arm_output_function_prologue (FILE *); static int arm_comp_type_attributes (const_tree, const_tree); @@ -375,7 +376,8 @@ static const struct attribute_spec arm_attribute_table[] = arm_handle_cmse_nonsecure_entry, NULL }, { "cmse_nonsecure_call", 0, 0, true, false, false, true, arm_handle_cmse_nonsecure_call, NULL }, - { NULL, 0, 0, false, false, false, false, NULL, NULL } + { "noinit", 0, 0, true, false, false, false, arm_data_attr, NULL }, + { NULL, 0, 0, false, false, false, false, NULL, NULL }, }; /* Initialize the GCC target structure. */ @@ -808,6 +810,10 @@ static const struct attribute_spec arm_attribute_table[] = #undef TARGET_CONSTANT_ALIGNMENT #define TARGET_CONSTANT_ALIGNMENT arm_constant_alignment + +#undef TARGET_ASM_SELECT_SECTION +#define TARGET_ASM_SELECT_SECTION arm_select_section + /* Obstack for minipool constant handling. */ static struct obstack minipool_obstack; @@ -7150,6 +7156,47 @@ arm_handle_cmse_nonsecure_call (tree *node, tree name, return NULL_TREE; } +/* Called when the noinit attribute is used. 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 +arm_data_attr (tree * node, + tree name, + tree args ATTRIBUTE_UNUSED, + int flags ATTRIBUTE_UNUSED, + bool * no_add_attrs ATTRIBUTE_UNUSED) +{ + 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; +} + /* Return 0 if the attributes for two types are incompatible, 1 if they are compatible, and 2 if they are nearly compatible (which causes a warning to be generated). */ @@ -27890,6 +27937,8 @@ arm_asm_emit_except_personality (rtx personality) /* Implement TARGET_ASM_INITIALIZE_SECTIONS. */ +static section *noinit_section; + static void arm_asm_init_sections (void) { @@ -27902,6 +27951,19 @@ arm_asm_init_sections (void) if (target_pure_code) text_section->unnamed.data = "\t.section .text,\"0x20000006\",%progbits"; #endif + + noinit_section = get_unnamed_section (0, output_section_asm_op, ".section .noinit,\"aw\""); +} + +static section * +arm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align) +{ + gcc_assert (decl != NULL_TREE); + + if (DECL_P (decl) && lookup_attribute ("noinit", DECL_ATTRIBUTES (decl)) != NULL_TREE) + return noinit_section; + else + return default_elf_select_section (decl, reloc, align); } /* Output unwind directives for the start/end of a function. */ @@ -31520,6 +31582,9 @@ arm_elf_section_type_flags (tree decl, const char *name, int reloc) if (decl && TREE_CODE (decl) == FUNCTION_DECL && target_pure_code) flags |= SECTION_ARM_PURECODE; + if (strcmp (name, ".noinit") == 0) + flags = SECTION_WRITE | SECTION_BSS | SECTION_NOTYPE; + return flags; } diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 2520835..d544527 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -6684,6 +6684,7 @@ attributes. @menu * Common Variable Attributes:: * ARC Variable Attributes:: +* ARM Variable Attributes:: * AVR Variable Attributes:: * Blackfin Variable Attributes:: * H8/300 Variable Attributes:: @@ -7131,6 +7132,18 @@ given via attribute argument. @end table +@node ARM Variable Attributes +@subsection ARM Variable Attributes + +@table @code +@item noinit +@cindex @code{noinit} variable attribute, ARM +Any data with the @code{noinit} attribute will not be initialised by +the C runtime startup code, or the program loader. Not initialising +data in this way can reduce program startup times. + +@end table + @node AVR Variable Attributes @subsection AVR Variable Attributes diff --git a/gcc/testsuite/gcc.target/arm/data-attributes.c b/gcc/testsuite/gcc.target/arm/data-attributes.c new file mode 100644 index 0000000..323c8e0 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/data-attributes.c @@ -0,0 +1,51 @@ +/* { dg-do run { target { ! *-*-linux* } } } */ +/* { 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 +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/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 = .); + }