From patchwork Thu Sep 23 02:02:07 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: 45325 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8A9E63857C48 for ; Thu, 23 Sep 2021 02:04:28 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8A9E63857C48 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1632362668; bh=ZDwCqkxRBmJS+jzH5nw6PtRyveodgRDfDnGAdM5Mo/c=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=C87ZOC0rAG4ZPv85+t2ekyQ6yvG6Xfb+DxP13Wu22YK+zdkP4LO/BE8EzCv9eB/Te 7BgHH+oRLhXsHHIT2/ms/fvmPPyPSDNDseZQU7k7RSfPQiAh0vW+gp3r94hBfhebZJ oWYJrGB4XpXGef/RfPOD+h66SQjvdhiRaEjVEZ1c= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pg1-x529.google.com (mail-pg1-x529.google.com [IPv6:2607:f8b0:4864:20::529]) by sourceware.org (Postfix) with ESMTPS id A59FC3857C44 for ; Thu, 23 Sep 2021 02:02:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A59FC3857C44 Received: by mail-pg1-x529.google.com with SMTP id t1so4777268pgv.3 for ; Wed, 22 Sep 2021 19:02:18 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ZDwCqkxRBmJS+jzH5nw6PtRyveodgRDfDnGAdM5Mo/c=; b=afvIXCSwWAxOBeTl0rgsCCFvavMNmzp4yHcV3ERuFOppaat+9pB9inz2zspd9AMlzX zEMdFXbeBlg+3X6fioeoxCoYF7LCBkx9sK/LzBjMTffQjtL/glE/5W8U4Mcum8YahDuN KxqTj2de4FwuuFd/UCbGWRl1oy/RgVaMv3+o9oxmYnBKahRllH8u9joT76sC4ssGt3B0 hJWZca/vpSuXAIdHFpXjG52LMKvby5H9dZiWyp96M+3zBomTGNtsAs02BZXPlP+iq88P QCzpjew+jdfJANlLQivn8nTMj6iBddEsDBIUqxajUBDo730u4gI7Lw7s/8lWbUqlCzqT sYfg== X-Gm-Message-State: AOAM532/aFFafhtfAcICHVbxw2gVqUSyitkAWPihaI8Q9dLAshJ0JOLW 25iOKsxkhcTDN/tpAraXHEhOVqSn12A= X-Google-Smtp-Source: ABdhPJy9gAT1RQcrqCH2FlKTU8rGmuYwgaDC7R6vOgFrUK2lAMuJsnagkgWYLrpTYk+tCmpmvRWF6A== X-Received: by 2002:a63:ce57:: with SMTP id r23mr1886128pgi.271.1632362537068; Wed, 22 Sep 2021 19:02:17 -0700 (PDT) Received: from gnu-gram-1.localdomain (2603-800c-230f-d241-0000-0000-0000-112a.res6.spectrum.com. [2603:800c:230f:d241::112a]) by smtp.gmail.com with ESMTPSA id bv16sm3395076pjb.12.2021.09.22.19.02.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Sep 2021 19:02:16 -0700 (PDT) Received: from gnu-gram-1.localdomain (localhost [IPv6:::1]) by gnu-gram-1.localdomain (Postfix) with ESMTP id 35C89E0074; Wed, 22 Sep 2021 19:02:15 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH v4 2/2] Add TARGET_ASM_EMIT_GNU_PROPERTY_NOTE Date: Wed, 22 Sep 2021 19:02:07 -0700 Message-Id: <20210923020207.1414230-3-hjl.tools@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210923020207.1414230-1-hjl.tools@gmail.com> References: <20210923020207.1414230-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3032.8 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.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Florian Weimer , Jakub Jelinek Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Generate the marker for -fno-direct-extern-access to indicate that the object file uses GOT to access all external symbols. Access to protected symbols in the resulting shared library is treated as local, which requires canonical function pointers and cannot be used with copy relocation. This marker can be used in the following ways: 1. Linker can decide the best way to resolve a relocation against a protected symbol before seeing all relocations against the symbol. 2. Dynamic linker can decide if it is an error to have a copy relocation in executable against the protected symbol in a shared library by checking if the shared library is built with -fno-direct-extern-access. * configure.ac (HAVE_LD_INDIRECT_EXTERN_ACCESS_SUPPORT): New. Define to 1 if linker supports GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. * output.h (emit_gnu_property): New. (emit_gnu_property_note): Likewise. * target.def (emit_gnu_property_note): Add a argetm.asm_out hook. * toplev.c (compile_file): Call emit_gnu_property_note before file_end. * varasm.c (emit_gnu_property): New. (emit_gnu_property_note): Likewise. * config.in: Regenerated. * configure: Likewise. * doc/tm.texi: Likewise. * config/i386/gnu-property.c (emit_gnu_property): Removed. (TARGET_ASM_EMIT_GNU_PROPERTY_NOTE): New. * doc/tm.texi.in: Add TARGET_ASM_EMIT_GNU_PROPERTY_NOTE. --- gcc/config.in | 7 +++++ gcc/config/i386/gnu-property.c | 31 ---------------------- gcc/config/i386/i386.c | 2 ++ gcc/configure | 27 +++++++++++++++++++ gcc/configure.ac | 23 +++++++++++++++++ gcc/doc/tm.texi | 5 ++++ gcc/doc/tm.texi.in | 2 ++ gcc/output.h | 2 ++ gcc/target.def | 8 ++++++ gcc/toplev.c | 3 +++ gcc/varasm.c | 47 ++++++++++++++++++++++++++++++++++ 11 files changed, 126 insertions(+), 31 deletions(-) diff --git a/gcc/config.in b/gcc/config.in index 61cafe4f6c0..8a756aa3541 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -1690,6 +1690,13 @@ #endif +/* Define to 1 if your linker supports + GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. */ +#ifndef USED_FOR_TARGET +#undef HAVE_LD_INDIRECT_EXTERN_ACCESS_SUPPORT +#endif + + /* Define if your PowerPC64 linker supports a large TOC. */ #ifndef USED_FOR_TARGET #undef HAVE_LD_LARGE_TOC diff --git a/gcc/config/i386/gnu-property.c b/gcc/config/i386/gnu-property.c index 4ba04403002..9fe8d00132e 100644 --- a/gcc/config/i386/gnu-property.c +++ b/gcc/config/i386/gnu-property.c @@ -24,37 +24,6 @@ along with GCC; see the file COPYING3. If not see #include "output.h" #include "linux-common.h" -static void -emit_gnu_property (unsigned int type, unsigned int data) -{ - int p2align = ptr_mode == SImode ? 2 : 3; - - switch_to_section (get_section (".note.gnu.property", - SECTION_NOTYPE, NULL)); - - ASM_OUTPUT_ALIGN (asm_out_file, p2align); - /* name length. */ - fprintf (asm_out_file, ASM_LONG "1f - 0f\n"); - /* data length. */ - fprintf (asm_out_file, ASM_LONG "4f - 1f\n"); - /* note type: NT_GNU_PROPERTY_TYPE_0. */ - fprintf (asm_out_file, ASM_LONG "5\n"); - fprintf (asm_out_file, "0:\n"); - /* vendor name: "GNU". */ - fprintf (asm_out_file, STRING_ASM_OP "\"GNU\"\n"); - fprintf (asm_out_file, "1:\n"); - ASM_OUTPUT_ALIGN (asm_out_file, p2align); - /* pr_type. */ - fprintf (asm_out_file, ASM_LONG "0x%x\n", type); - /* pr_datasz. */ - fprintf (asm_out_file, ASM_LONG "3f - 2f\n"); - fprintf (asm_out_file, "2:\n"); - fprintf (asm_out_file, ASM_LONG "0x%x\n", data); - fprintf (asm_out_file, "3:\n"); - ASM_OUTPUT_ALIGN (asm_out_file, p2align); - fprintf (asm_out_file, "4:\n"); -} - void file_end_indicate_exec_stack_and_gnu_property (void) { diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 9ca1ef512a4..3b678c4d5b6 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -24569,6 +24569,8 @@ ix86_libgcc_floating_mode_supported_p #if !TARGET_MACHO && !TARGET_DLLIMPORT_DECL_ATTRIBUTES # undef TARGET_ASM_RELOC_RW_MASK # define TARGET_ASM_RELOC_RW_MASK ix86_reloc_rw_mask +# undef TARGET_ASM_EMIT_GNU_PROPERTY_NOTE +# define TARGET_ASM_EMIT_GNU_PROPERTY_NOTE emit_gnu_property_note #endif static bool ix86_libc_has_fast_function (int fcode ATTRIBUTE_UNUSED) diff --git a/gcc/configure b/gcc/configure index b3de17009b8..13fe041b0b6 100755 --- a/gcc/configure +++ b/gcc/configure @@ -32172,6 +32172,33 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_bndplt_support" >&5 $as_echo "$ld_bndplt_support" >&6; } +# Check if linker supports GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. +ld_indirect_extern_access=0 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker with GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS" >&5 +$as_echo_n "checking linker with GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS... " >&6; } +if test x"$ld_is_gold" = xno; then + # GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS supported was added to + # GNU linker for binutils 2.38 on 2021-07-09. + if test $in_tree_ld = yes ; then + if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 38 -o "$gcc_cv_gld_major_version" -gt 2; then + ld_indirect_extern_access=1 + fi + elif echo "$ld_ver" | grep GNU > /dev/null; then + if test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -ge 37 -a "$ld_vers_patch" -ge 50 -a 0"$ld_date" -gt 20210709; then + ld_indirect_extern_access=1 + elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -ge 38 -o "$ld_vers_major" -gt 2; then + ld_indirect_extern_access=1 + fi + fi +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_LD_INDIRECT_EXTERN_ACCESS_SUPPORT $ld_indirect_extern_access +_ACEOF + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_indirect_extern_access" >&5 +$as_echo "$ld_indirect_extern_access" >&6; } + # Check linker supports '--push-state'/'--pop-state' ld_pushpopstate_support=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker --push-state/--pop-state options" >&5 diff --git a/gcc/configure.ac b/gcc/configure.ac index 7d3aab47030..d707ea85d5c 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -7526,6 +7526,29 @@ if test x"$ld_bndplt_support" = xyes; then fi AC_MSG_RESULT($ld_bndplt_support) +# Check if linker supports GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. +ld_indirect_extern_access=0 +AC_MSG_CHECKING(linker with GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS) +if test x"$ld_is_gold" = xno; then + # GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS supported was added to + # GNU linker for binutils 2.38 on 2021-07-09. + if test $in_tree_ld = yes ; then + if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 38 -o "$gcc_cv_gld_major_version" -gt 2; then + ld_indirect_extern_access=1 + fi + elif echo "$ld_ver" | grep GNU > /dev/null; then + if test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -ge 37 -a "$ld_vers_patch" -ge 50 -a 0"$ld_date" -gt 20210709; then + ld_indirect_extern_access=1 + elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -ge 38 -o "$ld_vers_major" -gt 2; then + ld_indirect_extern_access=1 + fi + fi +fi +AC_DEFINE_UNQUOTED(HAVE_LD_INDIRECT_EXTERN_ACCESS_SUPPORT, + $ld_indirect_extern_access, + [Define to 1 if your linker supports GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.]) +AC_MSG_RESULT($ld_indirect_extern_access) + # Check linker supports '--push-state'/'--pop-state' ld_pushpopstate_support=no AC_MSG_CHECKING(linker --push-state/--pop-state options) diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 902402d7503..3f65dc8387c 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -8095,6 +8095,11 @@ Output to @code{asm_out_file} any text which the assembler expects to find at the end of a file. The default is to output nothing. @end deftypefn +@deftypefn {Target Hook} void TARGET_ASM_EMIT_GNU_PROPERTY_NOTE (void) +Output a GNU property note to @code{asm_out_file}. The default is to +output nothing. +@end deftypefn + @deftypefun void file_end_indicate_exec_stack () Some systems use a common convention, the @samp{.note.GNU-stack} special section, to indicate whether or not an object file relies on diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 86352dc9bd2..5e48a29e55e 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -5057,6 +5057,8 @@ This describes the overall framework of an assembly file. @hook TARGET_ASM_FILE_END +@hook TARGET_ASM_EMIT_GNU_PROPERTY_NOTE + @deftypefun void file_end_indicate_exec_stack () Some systems use a common convention, the @samp{.note.GNU-stack} special section, to indicate whether or not an object file relies on diff --git a/gcc/output.h b/gcc/output.h index 73ca4545f4f..f9cbf7cab37 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -607,6 +607,8 @@ extern void default_asm_declare_constant_name (FILE *, const char *, extern void default_file_start (void); extern void file_end_indicate_exec_stack (void); extern void file_end_indicate_split_stack (void); +extern void emit_gnu_property (unsigned int, unsigned int); +extern void emit_gnu_property_note (void); extern void default_elf_asm_output_external (FILE *file, tree, const char *); diff --git a/gcc/target.def b/gcc/target.def index c5d90cace80..e27c0f7c0f8 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -715,6 +715,14 @@ to find at the end of a file. The default is to output nothing.", void, (void), hook_void_void) +/* Output a GNU property note. */ +DEFHOOK +(emit_gnu_property_note, + "Output a GNU property note to @code{asm_out_file}. The default is to\n\ +output nothing.", + void, (void), + hook_void_void) + /* Output any boilerplate text needed at the beginning of an LTO output stream. */ DEFHOOK diff --git a/gcc/toplev.c b/gcc/toplev.c index 14d1335e79e..38decb1e8eb 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -586,6 +586,9 @@ compile_file (void) /* Invoke registered plugin callbacks. */ invoke_plugin_callbacks (PLUGIN_FINISH_UNIT, NULL); + /* Output a GNU property note. */ + targetm.asm_out.emit_gnu_property_note (); + /* This must be at the end. Some target ports emit end of file directives into the assembly file here, and hence we cannot output anything to the assembly file after this point. */ diff --git a/gcc/varasm.c b/gcc/varasm.c index 2d261b353bf..aa97ae91d4e 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -7735,6 +7735,53 @@ default_file_start (void) } } +/* Emit one GNU property of TYPE and DATA. */ + +void +emit_gnu_property (unsigned int type, unsigned int data) +{ + int p2align = ptr_mode == SImode ? 2 : 3; + + switch_to_section (get_section (".note.gnu.property", + SECTION_NOTYPE, NULL)); + + ASM_OUTPUT_ALIGN (asm_out_file, p2align); + /* name length. */ + fprintf (asm_out_file, ASM_LONG "1f - 0f\n"); + /* data length. */ + fprintf (asm_out_file, ASM_LONG "4f - 1f\n"); + /* note type: NT_GNU_PROPERTY_TYPE_0. */ + fprintf (asm_out_file, ASM_LONG "5\n"); + fprintf (asm_out_file, "0:\n"); + /* vendor name: "GNU". */ + fprintf (asm_out_file, STRING_ASM_OP "\"GNU\"\n"); + fprintf (asm_out_file, "1:\n"); + ASM_OUTPUT_ALIGN (asm_out_file, p2align); + /* pr_type. */ + fprintf (asm_out_file, ASM_LONG "0x%x\n", type); + /* pr_datasz. */ + fprintf (asm_out_file, ASM_LONG "3f - 2f\n"); + fprintf (asm_out_file, "2:\n"); + fprintf (asm_out_file, ASM_LONG "0x%x\n", data); + fprintf (asm_out_file, "3:\n"); + ASM_OUTPUT_ALIGN (asm_out_file, p2align); + fprintf (asm_out_file, "4:\n"); +} + +/* This is a generic routine for TARGET_ASM_EMIT_GNU_PROPERTY_NOTE to + emit a NT_GNU_PROPERTY_TYPE_0 note. This is primarily a GNU extension + to ELF but could be used on other targets. */ + +void +emit_gnu_property_note (void) +{ + if (HAVE_LD_INDIRECT_EXTERN_ACCESS_SUPPORT + && !flag_direct_extern_access) + /* Emite a GNU_PROPERTY_1_NEEDED note with + GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS. */ + emit_gnu_property (0xb0008000, (1U << 0)); +} + /* This is a generic routine suitable for use as TARGET_ASM_FILE_END which emits a special section directive used to indicate whether or not this object file needs an executable stack. This is primarily