From patchwork Tue Nov 3 17:40:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jozef Lawrynowicz X-Patchwork-Id: 1393261 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; dmarc=none (p=none dis=none) header.from=mittosystems.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=mittosystems.com header.i=@mittosystems.com header.a=rsa-sha256 header.s=google header.b=RwN49gx7; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [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 4CQcW83zkKz9sSn for ; Wed, 4 Nov 2020 04:40:19 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DBE6E3854802; Tue, 3 Nov 2020 17:40:15 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by sourceware.org (Postfix) with ESMTPS id 14A0F385783A for ; Tue, 3 Nov 2020 17:40:11 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 14A0F385783A Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=mittosystems.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=jozef.l@mittosystems.com Received: by mail-wr1-x435.google.com with SMTP id n18so19410833wrs.5 for ; Tue, 03 Nov 2020 09:40:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mittosystems.com; s=google; h=date:from:to:subject:message-id:mail-followup-to:mime-version :content-disposition; bh=eziCMDFxJbnMS5tF/tO+Gd/zMNTqvtMRKluNYd+QW9s=; b=RwN49gx71irWT+6lgtHKZq9nwzfgxeXP9L+qMeZEsnsMOQWk+aelCIkGSfvk/c+XVA glm2HJYu/kHPfD41zKJZlqoGwTzZQtRLgnbT7nD2saEPL6CEZO24xpPo7Xp4swLVNTu+ rNKp1VyjEOfZrHD7ZrHy1p6DDPZRBDjGDwW1YU/NyZ9cl258q+16K0AyzpMyCu8zj5GR 2FYsA0ZBWX1ejNPofzSFI4wkwA9vusnmP6naNWUlfRlst6DfxuyuCUh1l4JWd+7ueLCq +DxxeCVBEQcsI4yu26nKJC0Ig9GcCUgvaPwchzhVr43Y1HbP3uJgPZy51cmPcdqXq6J6 VFgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mail-followup-to :mime-version:content-disposition; bh=eziCMDFxJbnMS5tF/tO+Gd/zMNTqvtMRKluNYd+QW9s=; b=gGmgbkhG/oxZz62RJp/vF99R1i4DuzKPjrytWlgrd6254oOjN9obWIsiIyBSsY8THd opaVy6zHYtG1zMNKpsmiNvu8hPR5OCiojCqiCPbu8+lfNB4844cQbV1onnrSeI+J+wnG vLiWjUo38ZveBdjI5c9b2pEuH91IXoP5SiiDTwKOAFs0oPf+CctYjf1VcIfJiu+htoVl pUXsFX9lTOw9bCq1/8Xr8+9/dSh9GWAV8QbpsjzlAqoP4s3ipKxLgnyTaikWxMUcxTI2 o8rSuRvoBL1o/KIZTj2lw1VmUp/gRX8r3YKPUmz7xyYuZ7LpslBmJXRDNnbz/m0F4LWY p4WQ== X-Gm-Message-State: AOAM532iLf7KhBXLvMgmw+/+CfBYyK051VIC3IR5FYv+0zNoxQVBfAMo lf/T/eD7B5b8iC0m1tw4bjxZMOpqJm5dWldf X-Google-Smtp-Source: ABdhPJzHfZpYoel91mO1eNndk5lcW/IiQ2j9PHnVUM3PLgD9TBFuJQQICzRN6xoH5vCDQF0JsIv+Vw== X-Received: by 2002:adf:e50b:: with SMTP id j11mr28142953wrm.263.1604425209815; Tue, 03 Nov 2020 09:40:09 -0800 (PST) Received: from jozef-acer-manjaro ([2a01:4b00:87fd:900:5e1d:5c99:56da:76e8]) by smtp.gmail.com with ESMTPSA id s11sm26501040wrm.56.2020.11.03.09.40.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Nov 2020 09:40:08 -0800 (PST) Date: Tue, 3 Nov 2020 17:40:07 +0000 From: Jozef Lawrynowicz To: gcc-patches@gcc.gnu.org Subject: [PATCH] "used" attribute saves decl from linker garbage collection Message-ID: <20201103174007.sjcttm5nbqxl33na@jozef-acer-manjaro> Mail-Followup-To: gcc-patches@gcc.gnu.org MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, 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: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" The attached patch implements TARGET_ASM_MARK_DECL_PRESERVED for ELF GNU OSABI targets, so that declarations that have the "used" attribute applied will be saved from linker garbage collection. TARGET_ASM_MARK_DECL_PRESERVED will emit an assembler ".retain" directive for the decl, and the assembler will apply the SHF_GNU_RETAIN flag to the section containing the decl. The linker will not garbage collect sections marked with the SHF_GNU_RETAIN flag. SHF_GNU_RETAIN is a GNU OSABI ELF extension, and it was discussed on the GNU gABI mailing list here: https://sourceware.org/pipermail/gnu-gabi/2020q3/000429.html The Binutils patch to implement .retain and other SHF_GNU_RETAIN handling is posted here: https://sourceware.org/pipermail/binutils/2020-November/113993.html Successfully bootstrapped and regtested for x86_64-pc-linux-gnu, and regtested for arm-none-eabi. Ok for trunk? Thanks, Jozef From 0827e28480b7edd07cda4f938bdd14b1cbdf1fa2 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Thu, 29 Oct 2020 21:00:07 +0000 Subject: [PATCH] Implement TARGET_MARK_DECL_PRESERVED for ELF GNU OSABI targets The GAS .retain directive will apply the SHF_GNU_RETAIN flag to the section containing the symbol that must be preserved. gcc/ChangeLog: * config.in: Regenerate. * config/elfos.h (TARGET_ASM_MARK_DECL_PRESERVED): Define for HAVE_GAS_RETAIN. * configure: Regenerate. * configure.ac: Define HAVE_GAS_RETAIN. * doc/extend.texi (used attribute): Document saving from linker garbage collection. * doc/sourcebuild.texi: Document "retain" effective target keyword. * doc/tm.texi: Regenerate. * output.h (default_elf_mark_decl_preserved): New. * target.def (mark_decl_preserved): Mention GAS .retain directive. * varasm.c (default_elf_mark_decl_preserved): New. gcc/testsuite/ChangeLog: * c-c++-common/attr-used-2.c: Test for .retain in assembler output. * c-c++-common/attr-used.c: Likewise. * lib/target-supports.exp (check_effective_target_retain): New. --- gcc/config.in | 6 ++++ gcc/config/elfos.h | 7 +++++ gcc/configure | 35 ++++++++++++++++++++++++ gcc/configure.ac | 8 ++++++ gcc/doc/extend.texi | 6 ++++ gcc/doc/sourcebuild.texi | 3 ++ gcc/doc/tm.texi | 2 +- gcc/output.h | 4 +++ gcc/target.def | 2 +- gcc/testsuite/c-c++-common/attr-used-2.c | 1 + gcc/testsuite/c-c++-common/attr-used.c | 2 ++ gcc/testsuite/lib/target-supports.exp | 9 ++++++ gcc/varasm.c | 13 +++++++++ 13 files changed, 96 insertions(+), 2 deletions(-) diff --git a/gcc/config.in b/gcc/config.in index 3657c46f349..8ef075a0ff3 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -1346,6 +1346,12 @@ #endif +/* Define if your assembler supports the .retain directive. */ +#ifndef USED_FOR_TARGET +#undef HAVE_GAS_RETAIN +#endif + + /* Define if your assembler supports specifying the exclude section flag. */ #ifndef USED_FOR_TARGET #undef HAVE_GAS_SECTION_EXCLUDE diff --git a/gcc/config/elfos.h b/gcc/config/elfos.h index 74a3eafda6b..fab7b0e8ea4 100644 --- a/gcc/config/elfos.h +++ b/gcc/config/elfos.h @@ -474,3 +474,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #undef TARGET_LIBC_HAS_FUNCTION #define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function + +/* If the assembler supports the .retain directive for saving a symbol + from linker garbage collection, define this macro. */ +#if HAVE_GAS_RETAIN +#undef TARGET_ASM_MARK_DECL_PRESERVED +#define TARGET_ASM_MARK_DECL_PRESERVED default_elf_mark_decl_preserved +#endif diff --git a/gcc/configure b/gcc/configure index abff47d30eb..37488eac25d 100755 --- a/gcc/configure +++ b/gcc/configure @@ -24223,6 +24223,41 @@ cat >>confdefs.h <<_ACEOF _ACEOF +# Test if the assembler supports the .retain directive for saving a symbol from +# linker garbage collection. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for retain directive" >&5 +$as_echo_n "checking assembler for retain directive... " >&6; } +if ${gcc_cv_as_retain_r+:} false; then : + $as_echo_n "(cached) " >&6 +else + gcc_cv_as_retain_r=no + if test x$gcc_cv_as != x; then + $as_echo '.retain retain_sym' > conftest.s + if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } + then + gcc_cv_as_retain_r=yes + else + echo "configure: failed program was" >&5 + cat conftest.s >&5 + fi + rm -f conftest.o conftest.s + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_retain_r" >&5 +$as_echo "$gcc_cv_as_retain_r" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define HAVE_GAS_RETAIN `if test $gcc_cv_as_retain_r = yes; then echo 1; else echo 0; fi` +_ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for section merging support" >&5 $as_echo_n "checking assembler for section merging support... " >&6; } if ${gcc_cv_as_shf_merge+:} false; then : diff --git a/gcc/configure.ac b/gcc/configure.ac index 26a5d8e3619..08b38d894a3 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -3216,6 +3216,14 @@ AC_DEFINE_UNQUOTED(HAVE_GAS_SECTION_EXCLUDE, [`if test $gcc_cv_as_section_exclude_e = yes || test $gcc_cv_as_section_exclude_hash = yes; then echo 1; else echo 0; fi`], [Define if your assembler supports specifying the exclude section flag.]) +# Test if the assembler supports the .retain directive for saving a symbol from +# linker garbage collection. +gcc_GAS_CHECK_FEATURE([retain directive], gcc_cv_as_retain_r,,, + [.retain retain_sym]) +AC_DEFINE_UNQUOTED(HAVE_GAS_RETAIN, + [`if test $gcc_cv_as_retain_r = yes; then echo 1; else echo 0; fi`], +[Define if your assembler supports the .retain directive.]) + gcc_GAS_CHECK_FEATURE(section merging support, gcc_cv_as_shf_merge, [elf,2,12,0], [--fatal-warnings], [.section .rodata.str, "aMS", @progbits, 1]) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 62549b02452..4f77a5c0229 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -3810,6 +3810,9 @@ 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. +As a GNU ELF extension, functions with this attribute will not be +garbage collected by the linker. + @item visibility ("@var{visibility_type}") @cindex @code{visibility} function attribute This attribute affects the linkage of the declaration to which it is attached. @@ -7269,6 +7272,9 @@ 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. +As a GNU ELF extension, variables with this attribute will not be +garbage collected by the linker. + @item vector_size (@var{bytes}) @cindex @code{vector_size} variable attribute This attribute specifies the vector size for the type of the declared diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index 49316a5d0ff..7fe77e7f09e 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -2551,6 +2551,9 @@ Target supports @option{-pie}, @option{-fpie} and @option{-fPIE}. @item rdynamic Target supports @option{-rdynamic}. +@item retain +Target supports the @code{.retain} assembler directive. + @item scalar_all_fma Target supports all four fused multiply-add optabs for both @code{float} and @code{double}. These optabs are: @code{fma_optab}, @code{fms_optab}, diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 97437e8274f..b074b2ff75b 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -8773,7 +8773,7 @@ library function is given by @var{symref}, which is a @code{symbol_ref}. @deftypefn {Target Hook} void TARGET_ASM_MARK_DECL_PRESERVED (const char *@var{symbol}) This target hook is a function to output to @var{asm_out_file} an assembler directive to annotate @var{symbol} as used. The Darwin target uses the -.no_dead_code_strip directive. +.no_dead_code_strip directive, and ELF targets use the .retain directive. @end deftypefn @defmac ASM_OUTPUT_LABELREF (@var{stream}, @var{name}) diff --git a/gcc/output.h b/gcc/output.h index eb253c50329..c0eba372c5d 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -609,6 +609,10 @@ extern void default_elf_init_array_asm_out_constructor (rtx, int); extern void default_elf_fini_array_asm_out_destructor (rtx, int); extern int maybe_assemble_visibility (tree); +#if HAVE_GAS_RETAIN +void default_elf_mark_decl_preserved (const char *); +#endif + extern int default_address_cost (rtx, machine_mode, addr_space_t, bool); /* Stack usage. */ diff --git a/gcc/target.def b/gcc/target.def index ed2da154e30..12164792b00 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -737,7 +737,7 @@ DEFHOOK (mark_decl_preserved, "This target hook is a function to output to @var{asm_out_file} an assembler\n\ directive to annotate @var{symbol} as used. The Darwin target uses the\n\ -.no_dead_code_strip directive.", +.no_dead_code_strip directive, and ELF targets use the .retain directive.", void, (const char *symbol), hook_void_constcharptr) diff --git a/gcc/testsuite/c-c++-common/attr-used-2.c b/gcc/testsuite/c-c++-common/attr-used-2.c index f78b94b53a9..cf1d25a5b27 100644 --- a/gcc/testsuite/c-c++-common/attr-used-2.c +++ b/gcc/testsuite/c-c++-common/attr-used-2.c @@ -9,3 +9,4 @@ void foo() } /* { dg-final { scan-assembler "xyzzy" } } */ +/* { dg-final { scan-assembler "\\.retain\t\.*xyzzy" { target retain } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-used.c b/gcc/testsuite/c-c++-common/attr-used.c index ba7705aaa77..65a2f029698 100644 --- a/gcc/testsuite/c-c++-common/attr-used.c +++ b/gcc/testsuite/c-c++-common/attr-used.c @@ -11,3 +11,5 @@ static void function_declaration_after(void) __attribute__((__used__)); /* { dg-final { scan-assembler "function_declaration_before" } } */ /* { dg-final { scan-assembler "function_declaration_after" } } */ +/* { dg-final { scan-assembler "\\.retain\t\.*function_declaration_before" { target retain } } } */ +/* { dg-final { scan-assembler "\\.retain\t\.*function_declaration_after" { target retain } } } */ diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 8439720baea..7c0e925f7b4 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -380,6 +380,15 @@ proc check_effective_target_noinit { } { return 0 } +# The .retain assembler directive is only supported by some targets. +# This proc returns 1 if it's supported, 0 if it's not. + +proc check_effective_target_retain { } { + return [check_no_compiler_messages retain_available object { + __asm__(".retain used_var"); + }] +} + ############################### # proc check_visibility_available { what_kind } ############################### diff --git a/gcc/varasm.c b/gcc/varasm.c index ea0b59cf44a..c38640456c4 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -8276,6 +8276,19 @@ default_elf_fini_array_asm_out_destructor (rtx symbol, int priority) assemble_addr_to_section (symbol, sec); } + +#if HAVE_GAS_RETAIN +/* Implement TARGET_ASM_MARK_DECL_PRESERVED for ELF targets that support the + .retain assembler directive. */ +void +default_elf_mark_decl_preserved (const char *name) +{ + fprintf (asm_out_file, "\t.retain\t"); + assemble_name (asm_out_file, name); + fputc ('\n', asm_out_file); +} +#endif + /* Default TARGET_ASM_OUTPUT_IDENT hook. This is a bit of a cheat. The real default is a no-op, but this