From patchwork Wed Feb 17 20:04:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 1441324 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=JHGpwaCa; dkim-atps=neutral Received: from sourceware.org (unknown [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Dgpjd0jmyz9sSC for ; Thu, 18 Feb 2021 07:05:23 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 95AED3947C38; Wed, 17 Feb 2021 20:05:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 95AED3947C38 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1613592315; bh=0ALbHrjD3mHRWFW9wgLSkxCuq4axwplFAjADXDSFXaM=; h=References:In-Reply-To:Date:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=JHGpwaCaTfCCiUxz1qtCTVN8SNcRbRrAK03LE5HH84ivuiFA0y97UMbyrPXuoQpN+ 6gzAc24HuLHuWYecqhpY/EPTF+IXQepH64funFP3teeiUsVTL3591g7ATJ6VnyqSlS pre/kS4vgPxnIL7Z+gM+HQ5dceaM1xZ4xApAFa3s= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-oi1-x229.google.com (mail-oi1-x229.google.com [IPv6:2607:f8b0:4864:20::229]) by sourceware.org (Postfix) with ESMTPS id 7676B3851C26 for ; Wed, 17 Feb 2021 20:05:11 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 7676B3851C26 Received: by mail-oi1-x229.google.com with SMTP id f3so16251951oiw.13 for ; Wed, 17 Feb 2021 12:05:11 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=0ALbHrjD3mHRWFW9wgLSkxCuq4axwplFAjADXDSFXaM=; b=AdLdhJnDmeXCRtsi0dMmWu+BRjrODdjEMmb5lSyShgJXS8yUg4YXelWb5Lq+Gx3hgX vOFKKJfppAGhAEj7NVDaFXkcbLC8wIVPdywy3xkHmc7w6QecZVJ792WSjJuwpjXF2Fzn 4g8dgtmng3JlNzwDefu2D+EWEWWOD+eLzNJfjS2if88eWt7cq8KfGtcRBWbzQ9d01loo CRCm5VXqwGDxlUEG+NcVe0ZGZj/rO+CMkqXCXgPRpePW8MOVKZyhl0M9WcrGXAmrND1T Rw5PGurMBsmVp1P0F22UwTb5cqjuDT5eEuc0eKk3lTrt/8q7l7E06ECDk5HwldhuRnDz Vl7A== X-Gm-Message-State: AOAM532PuROCy7SImQBxOU4g8fDv1SJkpP9Vh1MZ5EkhrSLXx7KCOy5F WInHKPH92Zh6cK0/dEY1MXfJLWVA+k8VL5bqWYQ= X-Google-Smtp-Source: ABdhPJzqecoOUIfSKELiNzaFAa385qwp0gwmXhKgLNJmZiAgg1SdM0btw6CdQrjgjXhpAnO2/VlrVkpWVPvNJLIZMn8= X-Received: by 2002:a54:468f:: with SMTP id k15mr367616oic.58.1613592310795; Wed, 17 Feb 2021 12:05:10 -0800 (PST) MIME-Version: 1.0 References: <20210215223507.39713-1-hjl.tools@gmail.com> <20210216164547.GC4020736@tucnak> <20210217142638.GO4020736@tucnak> <20210217185656.GP4020736@tucnak> In-Reply-To: <20210217185656.GP4020736@tucnak> Date: Wed, 17 Feb 2021 12:04:34 -0800 Message-ID: Subject: [PATCH v4] Add retain attribute to place symbols in SHF_GNU_RETAIN section To: Jakub Jelinek X-Spam-Status: No, score=-3035.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Gcc-patches" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: GCC Patches Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" On Wed, Feb 17, 2021 at 10:57 AM Jakub Jelinek wrote: > > On Wed, Feb 17, 2021 at 09:34:34AM -0800, H.J. Lu wrote: > > -fretain-used-symols. > > +/* Add the NAME attribute to *ANODE. */ > > + > > +static void > > +add_attribute (tree *anode, int flags, tree name, tree args, tree ns, > > + const bool cxx11_attr_p, > > + const struct attribute_spec *spec) > > Why do you need this and can't instead do what decl_attributes does > e.g. for "noipa" attribute? > > /* A "noipa" function attribute implies "noinline", "noclone" and "no_icf" > for those targets that support it. */ > if (TREE_CODE (*node) == FUNCTION_DECL > && attributes > && lookup_attribute ("noipa", attributes) != NULL > && lookup_attribute_spec (get_identifier ("noipa"))) > { > if (lookup_attribute ("noinline", attributes) == NULL) > attributes = tree_cons (get_identifier ("noinline"), NULL, attributes); > > if (lookup_attribute ("noclone", attributes) == NULL) > attributes = tree_cons (get_identifier ("noclone"), NULL, attributes); > > if (lookup_attribute ("no_icf", attributes) == NULL) > attributes = tree_cons (get_identifier ("no_icf"), NULL, attributes); > } > > Of course, for "used" attributes and flag_retain_used_symbols it would need > to be DECL_P, but otherwise pretty much the same thing. Fixed. > > --- a/gcc/common.opt > > +++ b/gcc/common.opt > > @@ -2404,6 +2404,10 @@ frerun-loop-opt > > Common Ignore > > Does nothing. Preserved for backward compatibility. > > > > +fretain-used-symols > > s/symols/symbols/ - many times in the patch. Fixed. > > +@item retain > > +@cindex @code{retain} function attribute > > +This attribute is the same as the @code{used} attribute, except > > +for ELF targets that support the GNU or FreeBSD OSABIs, this attribute > > I'm not sure "retain" attribute should imply "used", one can always use > __attribute__((used, retain)) if one wants both. > I think it should only imply the GC avoidance and nothing else. > Fixed. Here is the updated patch. From 0521e87ee76cbcfc560289c78ae683764da0d964 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 15 Feb 2021 11:31:12 -0800 Subject: [PATCH v4] Add retain attribute to place symbols in SHF_GNU_RETAIN section When building Linux kernel, ld in bninutils 2.36 with GCC 11 generates thousands of ld: warning: orphan section `.data.event_initcall_finish' from `init/main.o' being placed in section `.data.event_initcall_finish' ld: warning: orphan section `.data.event_initcall_start' from `init/main.o' being placed in section `.data.event_initcall_start' ld: warning: orphan section `.data.event_initcall_level' from `init/main.o' being placed in section `.data.event_initcall_level' Since these sections are marked with SHF_GNU_RETAIN, they are placed in separate sections. They become orphan sections since they aren't expected in the Linux kernel linker script. But orphan sections normally don't work well with the Linux kernel linker script and the resulting kernel crashed. 1. Add the "retain" attribute to place symbols in separate SHF_GNU_RETAIN sections. Issue a warning if the configured assembler/linker doesn't support SHF_GNU_RETAIN. 2. Add -fretain-used-symbols to treat symbols with the "used" attribute the same as the @code{retain} attribute. gcc/ PR target/99113 * attribs.c (decl_attributes): Imply "retain" attribute for "used" attribute when -fretain-used-symbols is used. * common.opt: Add -fretain-used-symbols. * toplev.c (process_options): Issue a warning for -fretain-used-symbols without SUPPORTS_SHF_GNU_RETAIN. * varasm.c (get_section): Replace SUPPORTS_SHF_GNU_RETAIN with looking up the retain attribute. (resolve_unique_section): Likewise. (get_variable_section): Likewise. (switch_to_section): Likewise. * doc/extend.texi: Document the "retain" attribute. * doc/invoke.texi: Document -fretain-used-symbols. gcc/c-family/ PR target/99113 * c-attribs.c (c_common_attribute_table): Add the "retain" attribute. (handle_retain_attribute): New function. gcc/testsuite/ PR target/99113 * c-c++-common/attr-retain-1.c: New test. * c-c++-common/attr-retain-2.c: Likewise. * c-c++-common/attr-retain-3.c: Likewise. * c-c++-common/attr-retain-4.c: Likewise. * c-c++-common/pr99113.c: Likewise. * gcc.c-torture/compile/attr-retain-1.c: Likewise. * gcc.c-torture/compile/attr-retain-2.c: Likewise. * c-c++-common/attr-used.c: Pass -fretain-used-symbols if supported. * c-c++-common/attr-used-2.c: Likewise. * c-c++-common/attr-used-3.c: Likewise. * c-c++-common/attr-used-4.c: Likewise. * c-c++-common/attr-used-5.c: Likewise. * c-c++-common/attr-used-6.c: Likewise. * c-c++-common/attr-used-7.c: Likewise. * c-c++-common/attr-used-8.c: Likewise. * c-c++-common/attr-used-9.c: Likewise. * gcc.c-torture/compile/attr-used-retain-1.c: Pass -fretain-used-symbols. * gcc.c-torture/compile/attr-used-retain-2.c: Likewise. --- gcc/attribs.c | 14 ++++++++ gcc/c-family/c-attribs.c | 26 ++++++++++++++ gcc/common.opt | 4 +++ gcc/doc/extend.texi | 8 +++-- gcc/doc/invoke.texi | 5 +++ gcc/testsuite/c-c++-common/attr-retain-1.c | 16 +++++++++ gcc/testsuite/c-c++-common/attr-retain-2.c | 12 +++++++ gcc/testsuite/c-c++-common/attr-retain-3.c | 7 ++++ gcc/testsuite/c-c++-common/attr-retain-4.c | 7 ++++ gcc/testsuite/c-c++-common/attr-used-2.c | 1 + gcc/testsuite/c-c++-common/attr-used-3.c | 1 + gcc/testsuite/c-c++-common/attr-used-4.c | 1 + gcc/testsuite/c-c++-common/attr-used-5.c | 1 + gcc/testsuite/c-c++-common/attr-used-6.c | 1 + gcc/testsuite/c-c++-common/attr-used-7.c | 1 + gcc/testsuite/c-c++-common/attr-used-8.c | 1 + gcc/testsuite/c-c++-common/attr-used-9.c | 1 + gcc/testsuite/c-c++-common/attr-used.c | 1 + gcc/testsuite/c-c++-common/pr99113.c | 7 ++++ .../gcc.c-torture/compile/attr-retain-1.c | 34 +++++++++++++++++++ .../gcc.c-torture/compile/attr-retain-2.c | 15 ++++++++ .../compile/attr-used-retain-1.c | 1 + .../compile/attr-used-retain-2.c | 2 +- gcc/toplev.c | 7 ++++ gcc/varasm.c | 20 ++++++----- 25 files changed, 183 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/attr-retain-1.c create mode 100644 gcc/testsuite/c-c++-common/attr-retain-2.c create mode 100644 gcc/testsuite/c-c++-common/attr-retain-3.c create mode 100644 gcc/testsuite/c-c++-common/attr-retain-4.c create mode 100644 gcc/testsuite/c-c++-common/pr99113.c create mode 100644 gcc/testsuite/gcc.c-torture/compile/attr-retain-1.c create mode 100644 gcc/testsuite/gcc.c-torture/compile/attr-retain-2.c diff --git a/gcc/attribs.c b/gcc/attribs.c index 81322d40f1d..226f669a1ee 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -546,6 +546,20 @@ decl_attributes (tree *node, tree attributes, int flags, attributes = tree_cons (get_identifier ("no_icf"), NULL, attributes); } + /* For -fretain-used-symbol, a "used" attribute also implies "retain". */ + if (flag_retain_used_symbols + && attributes + && (TREE_CODE (*node) == FUNCTION_DECL + || (VAR_P (*node) && TREE_STATIC (*node)) + || (TREE_CODE (*node) == TYPE_DECL)) + && lookup_attribute ("used", attributes) != NULL + && lookup_attribute_spec (get_identifier ("used"))) + { + if (lookup_attribute ("retain", attributes) == NULL) + attributes = tree_cons (get_identifier ("retain"), NULL, + attributes); + } + targetm.insert_attributes (*node, &attributes); /* Note that attributes on the same declaration are not necessarily diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index 0cb51fddfaa..71c850215dd 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -163,6 +163,7 @@ static tree handle_objc_root_class_attribute (tree *, tree, tree, int, bool *); static tree handle_objc_nullability_attribute (tree *, tree, tree, int, bool *); static tree handle_signed_bool_precision_attribute (tree *, tree, tree, int, bool *); +static tree handle_retain_attribute (tree *, tree, tree, int, bool *); /* Helper to define attribute exclusions. */ #define ATTR_EXCL(name, function, type, variable) \ @@ -328,6 +329,8 @@ const struct attribute_spec c_common_attribute_table[] = handle_used_attribute, NULL }, { "unused", 0, 0, false, false, false, false, handle_unused_attribute, NULL }, + { "retain", 0, 0, true, false, false, false, + handle_retain_attribute, NULL }, { "externally_visible", 0, 0, true, false, false, false, handle_externally_visible_attribute, NULL }, { "no_reorder", 0, 0, true, false, false, false, @@ -1564,6 +1567,29 @@ handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args), return NULL_TREE; } +/* Handle a "retain" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_retain_attribute (tree *pnode, tree name, tree ARG_UNUSED (args), + int ARG_UNUSED (flags), bool *no_add_attrs) +{ + tree node = *pnode; + + if (SUPPORTS_SHF_GNU_RETAIN + && (TREE_CODE (node) == FUNCTION_DECL + || (VAR_P (node) && TREE_STATIC (node)) + || (TREE_CODE (node) == TYPE_DECL))) + ; + else + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + + return NULL_TREE; +} + /* Handle a "externally_visible" attribute; arguments as in struct attribute_spec.handler. */ diff --git a/gcc/common.opt b/gcc/common.opt index c75dd36843e..70842481d4d 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2404,6 +2404,10 @@ frerun-loop-opt Common Ignore Does nothing. Preserved for backward compatibility. +fretain-used-symbols +Common Var(flag_retain_used_symbols) +Make the used attribute to imply the retain attribute if supported. + frounding-math Common Var(flag_rounding_math) Optimization SetByCombined Disable optimizations that assume default FP rounding behavior. diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 6eb1d327e97..8bbb93724a9 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -3913,8 +3913,10 @@ When applied to a member function of a C++ class template, the attribute also means that the function is instantiated if the class itself is instantiated. +@item retain +@cindex @code{retain} function attribute For ELF targets that support the GNU or FreeBSD OSABIs, this attribute -will also save the function from linker garbage collection. To support +will save the function from linker garbage collection. To support this behavior, functions that have not been placed in specific sections (e.g. by the @code{section} attribute, or the @code{-ffunction-sections} option), will be placed in new, unique sections. @@ -7504,8 +7506,10 @@ When applied to a static data member of a C++ class template, the attribute also means that the member is instantiated if the class itself is instantiated. +@item retain +@cindex @code{retain} variable attribute For ELF targets that support the GNU or FreeBSD OSABIs, this attribute -will also save the variable from linker garbage collection. To support +will save the variable from linker garbage collection. To support this behavior, variables that have not been placed in specific sections (e.g. by the @code{section} attribute, or the @code{-fdata-sections} option), will be placed in new, unique sections. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index e8baa545eee..2d2aff71439 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -16168,6 +16168,11 @@ DSOs; if your program relies on reinitialization of a DSO via @code{dlclose} and @code{dlopen}, you can use @option{-fno-gnu-unique}. +@item -fretain-used-symbols +@opindex fretain-used-symbols +On systems with recent GNU assembler and linker, the compiler makes +the @code{used} attribute to imply the @code{retain} attribute. + @item -fpcc-struct-return @opindex fpcc-struct-return Return ``short'' @code{struct} and @code{union} values in memory like diff --git a/gcc/testsuite/c-c++-common/attr-retain-1.c b/gcc/testsuite/c-c++-common/attr-retain-1.c new file mode 100644 index 00000000000..d060fbf22cd --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-retain-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target R_flag_in_section } } */ +/* { dg-options "-O3" } */ + +static void function_declaration_before(void) + __attribute__((__used__, __retain__)); + +static void function_declaration_before(void) {} + +static void function_declaration_after(void) {} + +static void function_declaration_after(void) + __attribute__((__used__, __retain__)); + +/* { dg-final { scan-assembler "function_declaration_before" } } */ +/* { dg-final { scan-assembler "function_declaration_after" } } */ +/* { dg-final { scan-assembler "\.text.*,\"axR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-retain-2.c b/gcc/testsuite/c-c++-common/attr-retain-2.c new file mode 100644 index 00000000000..6baba844adc --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-retain-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target R_flag_in_section } } */ +/* { dg-options "-Wall -O2" } */ + +static int xyzzy __attribute__((__used__, __retain__)) = 1; + +void foo() +{ + int x __attribute__((__retain__)); /* { dg-warning "attribute ignored|unused variable" } */ +} + +/* { dg-final { scan-assembler "xyzzy" } } */ +/* { dg-final { scan-assembler "\.data.*,\"awR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-retain-3.c b/gcc/testsuite/c-c++-common/attr-retain-3.c new file mode 100644 index 00000000000..a4077a1644d --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-retain-3.c @@ -0,0 +1,7 @@ +/* { dg-do compile { target R_flag_in_section } } */ +/* { dg-options "-Wall -O2 -fcommon" } */ + +static int xyzzy __attribute__((__used__, __retain__)); + +/* { dg-final { scan-assembler "xyzzy" } } */ +/* { dg-final { scan-assembler ",\"awR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-retain-4.c b/gcc/testsuite/c-c++-common/attr-retain-4.c new file mode 100644 index 00000000000..590e47cec86 --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-retain-4.c @@ -0,0 +1,7 @@ +/* { dg-do compile { target R_flag_in_section } } */ +/* { dg-options "-Wall -O2 -fcommon" } */ + +int xyzzy __attribute__((__used__, __retain__)); + +/* { dg-final { scan-assembler "xyzzy" } } */ +/* { dg-final { scan-assembler ",\"awR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-used-2.c b/gcc/testsuite/c-c++-common/attr-used-2.c index eef2519643f..2614e90bdfd 100644 --- a/gcc/testsuite/c-c++-common/attr-used-2.c +++ b/gcc/testsuite/c-c++-common/attr-used-2.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-Wall -O2" } */ +/* { dg-additional-options "-fretain-used-symbols" { target R_flag_in_section } } */ static int xyzzy __attribute__((__used__)) = 1; diff --git a/gcc/testsuite/c-c++-common/attr-used-3.c b/gcc/testsuite/c-c++-common/attr-used-3.c index ca64197929c..ea40d30ebb3 100644 --- a/gcc/testsuite/c-c++-common/attr-used-3.c +++ b/gcc/testsuite/c-c++-common/attr-used-3.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-Wall -O2 -fcommon" } */ +/* { dg-additional-options "-fretain-used-symbols" { target R_flag_in_section } } */ static int xyzzy __attribute__((__used__)); diff --git a/gcc/testsuite/c-c++-common/attr-used-4.c b/gcc/testsuite/c-c++-common/attr-used-4.c index 1cbc4c703e9..805d55e66b4 100644 --- a/gcc/testsuite/c-c++-common/attr-used-4.c +++ b/gcc/testsuite/c-c++-common/attr-used-4.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-Wall -O2 -fcommon" } */ +/* { dg-additional-options "-fretain-used-symbols" { target R_flag_in_section } } */ int xyzzy __attribute__((__used__)); diff --git a/gcc/testsuite/c-c++-common/attr-used-5.c b/gcc/testsuite/c-c++-common/attr-used-5.c index 5b4924160fd..0abdd527516 100644 --- a/gcc/testsuite/c-c++-common/attr-used-5.c +++ b/gcc/testsuite/c-c++-common/attr-used-5.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "non-ELF target" { *-*-darwin* } } */ /* { dg-options "-Wall -O2" } */ +/* { dg-additional-options "-fretain-used-symbols" { target R_flag_in_section } } */ struct dtv_slotinfo_list { diff --git a/gcc/testsuite/c-c++-common/attr-used-6.c b/gcc/testsuite/c-c++-common/attr-used-6.c index 3cf288dd28f..cf9b433dc24 100644 --- a/gcc/testsuite/c-c++-common/attr-used-6.c +++ b/gcc/testsuite/c-c++-common/attr-used-6.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "non-ELF target" { *-*-darwin* } } */ /* { dg-options "-Wall -O2" } */ +/* { dg-additional-options "-fretain-used-symbols" { target R_flag_in_section } } */ struct dtv_slotinfo_list { diff --git a/gcc/testsuite/c-c++-common/attr-used-7.c b/gcc/testsuite/c-c++-common/attr-used-7.c index 1721a8afc4e..2be2ecdb5da 100644 --- a/gcc/testsuite/c-c++-common/attr-used-7.c +++ b/gcc/testsuite/c-c++-common/attr-used-7.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "non-ELF target" { *-*-darwin* } } */ /* { dg-options "-Wall -O2" } */ +/* { dg-additional-options "-fretain-used-symbols" { target R_flag_in_section } } */ int __attribute__((used,section(".data.foo"))) foo2 = 2; int __attribute__((section(".data.foo"))) foo1 = 1; diff --git a/gcc/testsuite/c-c++-common/attr-used-8.c b/gcc/testsuite/c-c++-common/attr-used-8.c index 20662cadf70..9ebd9462880 100644 --- a/gcc/testsuite/c-c++-common/attr-used-8.c +++ b/gcc/testsuite/c-c++-common/attr-used-8.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "non-ELF target" { *-*-darwin* } } */ /* { dg-options "-Wall -O2" } */ +/* { dg-additional-options "-fretain-used-symbols" { target R_flag_in_section } } */ int __attribute__((section(".data.foo"))) foo1 = 1; /* { dg-warning "'.*' without 'used' attribute and '.*' with 'used' attribute are placed in a section with the same name" "" { target R_flag_in_section } .-1 } */ diff --git a/gcc/testsuite/c-c++-common/attr-used-9.c b/gcc/testsuite/c-c++-common/attr-used-9.c index 5847b0550ce..29d71512085 100644 --- a/gcc/testsuite/c-c++-common/attr-used-9.c +++ b/gcc/testsuite/c-c++-common/attr-used-9.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-skip-if "non-ELF target" { *-*-darwin* } } */ /* { dg-options "-Wall -O2" } */ +/* { dg-additional-options "-fretain-used-symbols" { target R_flag_in_section } } */ struct dtv_slotinfo_list { diff --git a/gcc/testsuite/c-c++-common/attr-used.c b/gcc/testsuite/c-c++-common/attr-used.c index 2036533c959..38480df3afa 100644 --- a/gcc/testsuite/c-c++-common/attr-used.c +++ b/gcc/testsuite/c-c++-common/attr-used.c @@ -1,5 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O3" } */ +/* { dg-additional-options "-fretain-used-symbols" { target R_flag_in_section } } */ static void function_declaration_before(void) __attribute__((__used__)); diff --git a/gcc/testsuite/c-c++-common/pr99113.c b/gcc/testsuite/c-c++-common/pr99113.c new file mode 100644 index 00000000000..01814014ac8 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr99113.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-Wall -O2" } */ + +static int xyzzy __attribute__((__used__)) = 1; + +/* { dg-final { scan-assembler "xyzzy" } } */ +/* { dg-final { scan-assembler-not "\.data.*,\"awR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/gcc.c-torture/compile/attr-retain-1.c b/gcc/testsuite/gcc.c-torture/compile/attr-retain-1.c new file mode 100644 index 00000000000..6cab15547cc --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/attr-retain-1.c @@ -0,0 +1,34 @@ +/* { dg-do compile { target R_flag_in_section } } */ +/* { dg-final { scan-assembler ".text.*,\"axR\"" } } */ +/* { dg-final { scan-assembler ".bss.*,\"awR\"" } } */ +/* { dg-final { scan-assembler ".data.*,\"awR\"" } } */ +/* { dg-final { scan-assembler ".rodata.*,\"aR\"" } } */ +/* { dg-final { scan-assembler ".data.used_foo_sec,\"awR\"" } } */ + +void __attribute__((used,retain)) used_fn (void) { } +void unused_fn (void) { } +void __attribute__((hot,used,retain)) used_hot_fn (void) { } +void __attribute__((hot)) unused_hot_fn (void) { } +void __attribute__((cold,used,retain)) used_cold_fn (void) { } +void __attribute__((cold)) unused_cold_fn (void) { } +int __attribute__((used,retain)) used_bss = 0; +int __attribute__((used,retain)) used_data = 1; +const int __attribute__((used,retain)) used_rodata = 2; +int __attribute__((used,retain)) used_comm; +static int __attribute__((used,retain)) used_lcomm; + +int unused_bss = 0; +int unused_data = 1; +const int unused_rodata = 2; +int unused_comm; +static int unused_lcomm; + +/* Test switching back to the used,retained sections. */ +void __attribute__((used,retain)) used_fn2 (void) { } +int __attribute__((used,retain)) used_bss2 = 0; +int __attribute__((used,retain)) used_data2 = 1; +const int __attribute__((used,retain)) used_rodata2 = 2; +int __attribute__((used,retain)) used_comm2; +static int __attribute__((used,retain)) used_lcomm2; + +int __attribute__((used,retain,section(".data.used_foo_sec"))) used_foo = 2; diff --git a/gcc/testsuite/gcc.c-torture/compile/attr-retain-2.c b/gcc/testsuite/gcc.c-torture/compile/attr-retain-2.c new file mode 100644 index 00000000000..0208ffe37ab --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/attr-retain-2.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target R_flag_in_section } } */ +/* { dg-final { scan-assembler ".text.used_fn,\"axR\"" } } */ +/* { dg-final { scan-assembler ".text.used_fn2,\"axR\"" } } */ +/* { dg-final { scan-assembler ".bss.used_bss,\"awR\"" } } */ +/* { dg-final { scan-assembler ".bss.used_bss2,\"awR\"" } } */ +/* { dg-final { scan-assembler ".data.used_data,\"awR\"" } } */ +/* { dg-final { scan-assembler ".data.used_data2,\"awR\"" } } */ +/* { dg-final { scan-assembler ".rodata.used_rodata,\"aR\"" } } */ +/* { dg-final { scan-assembler ".rodata.used_rodata2,\"aR\"" } } */ +/* { dg-final { scan-assembler ".bss.used_lcomm,\"awR\"" { target arm-*-* } } } */ +/* { dg-final { scan-assembler ".bss.used_lcomm2,\"awR\"" { target arm-*-* } } } */ +/* { dg-final { scan-assembler ".data.used_foo_sec,\"awR\"" } } */ +/* { dg-options "-ffunction-sections -fdata-sections" } */ + +#include "attr-retain-1.c" diff --git a/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-1.c b/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-1.c index 5f6cbca6e33..a1eea089ccd 100644 --- a/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-1.c @@ -5,6 +5,7 @@ /* { dg-final { scan-assembler ".data.*,\"awR\"" } } */ /* { dg-final { scan-assembler ".rodata.*,\"aR\"" } } */ /* { dg-final { scan-assembler ".data.used_foo_sec,\"awR\"" } } */ +/* { dg-options "-fretain-used-symbols" } */ void __attribute__((used)) used_fn (void) { } void unused_fn (void) { } diff --git a/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-2.c b/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-2.c index be5f3917ac8..a8c3a891b05 100644 --- a/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-2.c +++ b/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-2.c @@ -11,6 +11,6 @@ /* { dg-final { scan-assembler ".bss.used_lcomm,\"awR\"" { target arm-*-* } } } */ /* { dg-final { scan-assembler ".bss.used_lcomm2,\"awR\"" { target arm-*-* } } } */ /* { dg-final { scan-assembler ".data.used_foo_sec,\"awR\"" } } */ -/* { dg-options "-ffunction-sections -fdata-sections" } */ +/* { dg-options "-ffunction-sections -fdata-sections -fretain-used-symbols" } */ #include "attr-used-retain-1.c" diff --git a/gcc/toplev.c b/gcc/toplev.c index d8cc254adef..d84e89085a5 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1761,6 +1761,13 @@ process_options (void) if (flag_large_source_files) line_table->default_range_bits = 0; + if (flag_retain_used_symbols && !SUPPORTS_SHF_GNU_RETAIN) + { + warning_at (UNKNOWN_LOCATION, 0, "%qs is not supported for this target", + "-fretain-used-symbols"); + flag_retain_used_symbols = 0; + } + /* Please don't change global_options after this point, those changes won't be reflected in optimization_{default,current}_node. */ } diff --git a/gcc/varasm.c b/gcc/varasm.c index 29478ab0d8d..508820f29ac 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -297,10 +297,10 @@ get_section (const char *name, unsigned int flags, tree decl, slot = section_htab->find_slot_with_hash (name, htab_hash_string (name), INSERT); flags |= SECTION_NAMED; - if (SUPPORTS_SHF_GNU_RETAIN - && decl != nullptr + if (decl != nullptr && DECL_P (decl) - && DECL_PRESERVE_P (decl)) + && DECL_PRESERVE_P (decl) + && lookup_attribute ("retain", DECL_ATTRIBUTES (decl))) flags |= SECTION_RETAIN; if (*slot == NULL) { @@ -487,7 +487,8 @@ resolve_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED, if (DECL_SECTION_NAME (decl) == NULL && targetm_common.have_named_sections && (flag_function_or_data_sections - || (SUPPORTS_SHF_GNU_RETAIN && DECL_PRESERVE_P (decl)) + || (DECL_PRESERVE_P (decl) + && lookup_attribute ("retain", DECL_ATTRIBUTES (decl))) || DECL_COMDAT_GROUP (decl))) { targetm.asm_out.unique_section (decl, reloc); @@ -1227,7 +1228,8 @@ get_variable_section (tree decl, bool prefer_noswitch_p) vnode->get_constructor (); if (DECL_COMMON (decl) - && !(SUPPORTS_SHF_GNU_RETAIN && DECL_PRESERVE_P (decl))) + && !(DECL_PRESERVE_P (decl) + && lookup_attribute ("retain", DECL_ATTRIBUTES (decl)))) { /* If the decl has been given an explicit section name, or it resides in a non-generic address space, then it isn't common, and shouldn't @@ -7761,12 +7763,14 @@ switch_to_section (section *new_section, tree decl) { if (in_section == new_section) { - if (SUPPORTS_SHF_GNU_RETAIN - && (new_section->common.flags & SECTION_NAMED) + if ((new_section->common.flags & SECTION_NAMED) && decl != nullptr && DECL_P (decl) && (!!DECL_PRESERVE_P (decl) - != !!(new_section->common.flags & SECTION_RETAIN))) + != !!(new_section->common.flags & SECTION_RETAIN)) + && (lookup_attribute ("retain", + DECL_ATTRIBUTES (new_section->named.decl)) + || lookup_attribute ("retain", DECL_ATTRIBUTES (decl)))) { /* If the SECTION_RETAIN bit doesn't match, switch to a new section. */ -- 2.29.2