From patchwork Sun Jun 20 23:05:43 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: 1494829 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=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@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=Jakm+1Bu; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (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 4G7SvY2lBFz9sWM for ; Mon, 21 Jun 2021 09:06:15 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1F5FF385E83D for ; Sun, 20 Jun 2021 23:06:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1F5FF385E83D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1624230370; bh=UrHipn9tVIuvFFH9xw8IFeXgHXBY6galpciopjmyBN4=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=Jakm+1Bu0XVs3kR1oCuSgtrYneJonsvyd7inlD7xplVlOns5VD7dCURaAey1KxdQE P3SG88lXIL3Uz6F5loNlQkVu9Xram9/VF/Vsy25TgL5vR/qT6L3eeGqv8M3hk71Cis aKFSWFzCs4+N2I4pbp2m5rhn69gC6iGd5fp94lGc= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pg1-x52f.google.com (mail-pg1-x52f.google.com [IPv6:2607:f8b0:4864:20::52f]) by sourceware.org (Postfix) with ESMTPS id C37F3385741C for ; Sun, 20 Jun 2021 23:05:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C37F3385741C Received: by mail-pg1-x52f.google.com with SMTP id t9so12623442pgn.4 for ; Sun, 20 Jun 2021 16:05:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UrHipn9tVIuvFFH9xw8IFeXgHXBY6galpciopjmyBN4=; b=SMkVOA02f4cXRbvtSi4KLyUNR+fL0ZWJf+Z62j7fAxJNVqb9Yc30b2Vkqs29kOASZk WFA2DFplzSKqX5k2/dbIvGkXL8JAVMELHCxPPz6l8+DfVjt2ZeRmn8hqUJ8yBuvRzi0I 7oo3pRPF2HsNR+oz/lrUVnb6sV1Q4j3/RJT7/hC3ERJ5eJrcdWUhwK6R71hHZv6IfAMV uMebRTRtcNzPzxNlWUSFZ567uFfuDAvT9a1EZnCLXRaK5/Hfrb9aI8AXw+uufYBOWiUt HmuZUKvHt01+IKOvAvXx04TYK3pXN5wnl5qxiMsMW+dPhBGc8Le3bM59I41DV8aY3ZKa GpGQ== X-Gm-Message-State: AOAM531PQTM8yS/7Q0iT5EOb74M2yBuQa7hxuc85/uoRoX92CLcRdfHG iMN7Lu+c8Bd3Z+ZWeoc4E4o3pmXotsU= X-Google-Smtp-Source: ABdhPJyOdYKmibBVNh0kpGf/ItXkItwuQjDTCwjaPcUizxQxXcRhDCt/6Nv/tvCZStrJ/+nRTNsfEg== X-Received: by 2002:a65:528d:: with SMTP id y13mr21427166pgp.276.1624230346463; Sun, 20 Jun 2021 16:05:46 -0700 (PDT) Received: from gnu-cfl-2.localdomain ([172.56.39.115]) by smtp.gmail.com with ESMTPSA id a187sm13322703pfb.66.2021.06.20.16.05.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 20 Jun 2021 16:05:46 -0700 (PDT) Received: from gnu-cfl-2.. (localhost [IPv6:::1]) by gnu-cfl-2.localdomain (Postfix) with ESMTP id 67793C039E; Sun, 20 Jun 2021 16:05:44 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH 1/2] Add -fsingle-global-definition Date: Sun, 20 Jun 2021 16:05:43 -0700 Message-Id: <20210620230544.391025-2-hjl.tools@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210620230544.391025-1-hjl.tools@gmail.com> References: <20210620230544.391025-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3032.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_STOCKGEN, RCVD_IN_BARRACUDACENTRAL, 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" Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" 1. Generate a single global definition marker in relocatable objects. a. Always use GOT to access undefined data and function symbols, including in PIE and non-PIE. These will avoid copy relocations in executables. b. This is compatible with existing executables and shared libraries. 2. In executable and shared library, bind symbols with the STV_PROTECTED visibility locally: a. The address of data symbol is the address of data body. b. For systems without function descriptor, the function pointer is the address of function body. c. The resulting shared libraries may not be incompatible with executables which have copy relocations on protected symbols. 3. Update asm_preferred_eh_data_format to properly select EH encoding format with -fsingle-global-definition. 4. Add ix86_reloc_rw_mask for TARGET_ASM_RELOC_RW_MASK to avoid copy relocation with -fsingle-global-definition. gcc/ PR target/35513 PR target/100593 * common.opt: Add -fsingle-global-definition. * config/i386/i386-protos.h (ix86_force_load_from_GOT_p): Add a bool argument. * config/i386/i386.c (ix86_force_load_from_GOT_p): Add a bool argument to indicate call operand. Force non-call load from GOT for -fsingle-global-definition. (legitimate_pic_address_disp_p): Avoid copy relocation in PIE for -fsingle-global-definition. (ix86_print_operand): Pass true to ix86_force_load_from_GOT_p for call operand. (asm_preferred_eh_data_format): Use PC-relative format for -fsingle-global-definition to avoid copy relocation. Check ptr_mode instead of TARGET_64BIT when selecting DW_EH_PE_sdata4. (ix86_binds_local_p): Don't treat protected data as extern and avoid copy relocation on common symbol. (ix86_reloc_rw_mask): New to avoid copy relocation for -fsingle-global-definition. (TARGET_ASM_RELOC_RW_MASK): New. * doc/invoke.texi: Document -fsingle-global-definition. gcc/testsuite/ PR target/35513 PR target/100593 * g++.dg/pr35513-1.C: New file. * g++.dg/pr35513-2.C: Likewise. * gcc.target/i386/pr35513-1.c: Likewise. * gcc.target/i386/pr35513-2.c: Likewise. * gcc.target/i386/pr35513-3.c: Likewise. * gcc.target/i386/pr35513-4.c: Likewise. * gcc.target/i386/pr35513-5.c: Likewise. * gcc.target/i386/pr35513-6.c: Likewise. * gcc.target/i386/pr35513-7.c: Likewise. * gcc.target/i386/pr35513-8.c: Likewise. --- gcc/common.opt | 4 ++ gcc/config/i386/i386-protos.h | 2 +- gcc/config/i386/i386.c | 50 +++++++++++++++------ gcc/doc/invoke.texi | 8 +++- gcc/testsuite/g++.dg/pr35513-1.C | 25 +++++++++++ gcc/testsuite/g++.dg/pr35513-2.C | 53 +++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/pr35513-1.c | 16 +++++++ gcc/testsuite/gcc.target/i386/pr35513-2.c | 15 +++++++ gcc/testsuite/gcc.target/i386/pr35513-3.c | 15 +++++++ gcc/testsuite/gcc.target/i386/pr35513-4.c | 15 +++++++ gcc/testsuite/gcc.target/i386/pr35513-5.c | 15 +++++++ gcc/testsuite/gcc.target/i386/pr35513-6.c | 14 ++++++ gcc/testsuite/gcc.target/i386/pr35513-7.c | 15 +++++++ gcc/testsuite/gcc.target/i386/pr35513-8.c | 41 ++++++++++++++++++ 14 files changed, 272 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/g++.dg/pr35513-1.C create mode 100644 gcc/testsuite/g++.dg/pr35513-2.C create mode 100644 gcc/testsuite/gcc.target/i386/pr35513-1.c create mode 100644 gcc/testsuite/gcc.target/i386/pr35513-2.c create mode 100644 gcc/testsuite/gcc.target/i386/pr35513-3.c create mode 100644 gcc/testsuite/gcc.target/i386/pr35513-4.c create mode 100644 gcc/testsuite/gcc.target/i386/pr35513-5.c create mode 100644 gcc/testsuite/gcc.target/i386/pr35513-6.c create mode 100644 gcc/testsuite/gcc.target/i386/pr35513-7.c create mode 100644 gcc/testsuite/gcc.target/i386/pr35513-8.c diff --git a/gcc/common.opt b/gcc/common.opt index a1353e06bdc..b1cb53bb780 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2579,6 +2579,10 @@ fsigned-zeros Common Var(flag_signed_zeros) Init(1) Optimization SetByCombined Disable floating point optimizations that ignore the IEEE signedness of zero. +fsingle-global-definition +Common Var(flag_single_global_definition) Optimization +Use GOT to access external symbols and make access to protected symbols local. + fsingle-precision-constant Common Var(flag_single_precision_constant) Optimization Convert floating point constants to single precision constants. diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index e6ac9390777..30f75b9900b 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -77,7 +77,7 @@ extern bool ix86_expand_cmpstrn_or_cmpmem (rtx, rtx, rtx, rtx, rtx, bool); extern bool constant_address_p (rtx); extern bool legitimate_pic_operand_p (rtx); extern bool legitimate_pic_address_disp_p (rtx); -extern bool ix86_force_load_from_GOT_p (rtx); +extern bool ix86_force_load_from_GOT_p (rtx, bool = false); extern void print_reg (rtx, int, FILE*); extern void ix86_print_operand (FILE *, rtx, int); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 7d0d4143bca..9878c3126d0 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -10311,13 +10311,17 @@ darwin_local_data_pic (rtx disp) } /* True if the function symbol operand X should be loaded from GOT. + If CALL_P is true, X is a call operand. + + NB: -fsingle-global-definition doesn't force load from GOT for + call. NB: In 32-bit mode, only non-PIC is allowed in inline assembly statements, since a PIC register could not be available at the call site. */ bool -ix86_force_load_from_GOT_p (rtx x) +ix86_force_load_from_GOT_p (rtx x, bool call_p) { return ((TARGET_64BIT || (!flag_pic && HAVE_AS_IX86_GOT32X)) && !TARGET_PECOFF && !TARGET_MACHO @@ -10325,11 +10329,12 @@ ix86_force_load_from_GOT_p (rtx x) && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC && GET_CODE (x) == SYMBOL_REF - && SYMBOL_REF_FUNCTION_P (x) - && (!flag_plt - || (SYMBOL_REF_DECL (x) - && lookup_attribute ("noplt", - DECL_ATTRIBUTES (SYMBOL_REF_DECL (x))))) + && ((!call_p && flag_single_global_definition) + || (SYMBOL_REF_FUNCTION_P (x) + && (!flag_plt + || (SYMBOL_REF_DECL (x) + && lookup_attribute ("noplt", + DECL_ATTRIBUTES (SYMBOL_REF_DECL (x))))))) && !SYMBOL_REF_LOCAL_P (x)); } @@ -10595,7 +10600,8 @@ legitimate_pic_address_disp_p (rtx disp) } else if (!SYMBOL_REF_FAR_ADDR_P (op0) && (SYMBOL_REF_LOCAL_P (op0) - || (HAVE_LD_PIE_COPYRELOC + || (!flag_single_global_definition + && HAVE_LD_PIE_COPYRELOC && flag_pie && !SYMBOL_REF_WEAK (op0) && !SYMBOL_REF_FUNCTION_P (op0))) @@ -13497,7 +13503,7 @@ ix86_print_operand (FILE *file, rtx x, int code) if (code == 'P') { - if (ix86_force_load_from_GOT_p (x)) + if (ix86_force_load_from_GOT_p (x, true)) { /* For inline assembly statement, load function address from GOT with 'P' operand modifier to avoid PLT. */ @@ -21895,10 +21901,10 @@ ix86_stack_protect_fail (void) int asm_preferred_eh_data_format (int code, int global) { - if (flag_pic) + if (flag_pic || flag_single_global_definition) { int type = DW_EH_PE_sdata8; - if (!TARGET_64BIT + if (ptr_mode == SImode || ix86_cmodel == CM_SMALL_PIC || (ix86_cmodel == CM_MEDIUM_PIC && (global || code))) type = DW_EH_PE_sdata4; @@ -22986,10 +22992,21 @@ ix86_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update) static bool ix86_binds_local_p (const_tree exp) { - return default_binds_local_p_3 (exp, flag_shlib != 0, true, true, - (!flag_pic - || (TARGET_64BIT - && HAVE_LD_PIE_COPYRELOC != 0))); + return default_binds_local_p_3 (exp, flag_shlib != 0, true, + !flag_single_global_definition, + (!flag_single_global_definition + && (!flag_pic + || (TARGET_64BIT + && HAVE_LD_PIE_COPYRELOC != 0)))); +} + +/* If flag_pic or flag_single_global_definition is true, then neither + local nor global relocs should be placed in readonly memory. */ + +static int +ix86_reloc_rw_mask (void) +{ + return (flag_pic || flag_single_global_definition) ? 3 : 0; } #endif @@ -24016,6 +24033,11 @@ ix86_run_selftests (void) #define TARGET_GET_MULTILIB_ABI_NAME \ ix86_get_multilib_abi_name +#if !TARGET_MACHO && !TARGET_DLLIMPORT_DECL_ATTRIBUTES +# undef TARGET_ASM_RELOC_RW_MASK +# define TARGET_ASM_RELOC_RW_MASK ix86_reloc_rw_mask +#endif + static bool ix86_libc_has_fast_function (int fcode ATTRIBUTE_UNUSED) { #ifdef OPTION_GLIBC diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index af2ce189fae..203061e9c08 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -555,7 +555,7 @@ Objective-C and Objective-C++ Dialects}. -fselective-scheduling -fselective-scheduling2 @gol -fsel-sched-pipelining -fsel-sched-pipelining-outer-loops @gol -fsemantic-interposition -fshrink-wrap -fshrink-wrap-separate @gol --fsignaling-nans @gol +-fsignaling-nans -fsingle-global-definition @gol -fsingle-precision-constant -fsplit-ivs-in-unroller -fsplit-loops@gol -fsplit-paths @gol -fsplit-wide-types -fsplit-wide-types-early -fssa-backprop -fssa-phiopt @gol @@ -16543,6 +16543,12 @@ through the PLT for specific external functions. In position-dependent code, a few targets also convert calls to functions that are marked to not use the PLT to use the GOT instead. +@item -fsingle-global-definition +@opindex fsingle-global-definition +Avoid copy relocation by using the GOT pointer to access external symbols +in both position-dependent and position-independent codes. Make access +to protected symbols local. + @item -fno-jump-tables @opindex fno-jump-tables @opindex fjump-tables diff --git a/gcc/testsuite/g++.dg/pr35513-1.C b/gcc/testsuite/g++.dg/pr35513-1.C new file mode 100644 index 00000000000..861cf55c103 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr35513-1.C @@ -0,0 +1,25 @@ +// { dg-do run } +// { dg-options "-O2 -fsingle-global-definition" } + +#include + +class Bug +{ +}; + +int throw_bug() +{ + throw Bug(); + + return 0; +} + +int main() +{ + try { + std::cout << throw_bug(); + } catch (Bug bug) { + }; + + return 0; +} diff --git a/gcc/testsuite/g++.dg/pr35513-2.C b/gcc/testsuite/g++.dg/pr35513-2.C new file mode 100644 index 00000000000..a58144216d5 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr35513-2.C @@ -0,0 +1,53 @@ +// { dg-do run } +// { dg-options "-O2 -fsingle-global-definition" } + +class Foo +{ +public: + Foo(int n) : n_(n) { } + int f() { return n_; } + + int badTest(); + int goodTest(); + +private: + + int n_; +}; + +int Foo::badTest() +{ + try { + throw int(99); + } + + catch (int &i) { + n_ = 16; + } + + return n_; +} + + +int Foo::goodTest() +{ + int n; + + try { + throw int(99); + } + + catch (int &i) { + n = 16; + } + + return n_; +} + +int main() +{ + Foo foo(5); + foo.goodTest(); + foo.badTest(); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/pr35513-1.c b/gcc/testsuite/gcc.target/i386/pr35513-1.c new file mode 100644 index 00000000000..ec4c8aac049 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35513-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fsingle-global-definition" } */ + +extern void bar (void); +extern void *p; + +void +foo (void) +{ + p = &bar; +} + +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT," { target { ia32 && got32x_reloc } } } } */ +/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ia32 && got32x_reloc } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr35513-2.c b/gcc/testsuite/gcc.target/i386/pr35513-2.c new file mode 100644 index 00000000000..c5145d4d5ae --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35513-2.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fno-pic -fsingle-global-definition" } */ + +extern int bar; + +int +foo (void) +{ + return bar; +} + +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT," { target { ia32 && got32x_reloc } } } } */ +/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ia32 && got32x_reloc } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr35513-3.c b/gcc/testsuite/gcc.target/i386/pr35513-3.c new file mode 100644 index 00000000000..d0e93c84613 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35513-3.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fpie -fsingle-global-definition" } */ + +extern int bar; + +int +foo (void) +{ + return bar; +} + +/* { dg-final { scan-assembler "mov\(l|q\)\[ \t\]*bar@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "movl\[ \t\]*bar@GOT" { target { ia32 && got32x_reloc } } } } */ +/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "mov\(l|q\)\[ \t\]*\\\$bar," { target { ia32 && got32x_reloc } } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr35513-4.c b/gcc/testsuite/gcc.target/i386/pr35513-4.c new file mode 100644 index 00000000000..fffb7d878a8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35513-4.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fplt -fno-pic -fsingle-global-definition" } */ + +extern void foo (void); + +int +bar (void) +{ + foo (); + return 0; +} + +/* { dg-final { scan-assembler "call\[ \t\]*foo" } } */ +/* { dg-final { scan-assembler-not "foo@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "foo@GOT" { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr35513-5.c b/gcc/testsuite/gcc.target/i386/pr35513-5.c new file mode 100644 index 00000000000..a107611a104 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35513-5.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fplt -fpic -fsingle-global-definition" } */ + +extern void foo (void); + +int +bar (void) +{ + foo (); + return 0; +} + +/* { dg-final { scan-assembler "call\[ \t\]*foo@PLT" } } */ +/* { dg-final { scan-assembler-not "foo@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "foo@GOT" { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr35513-6.c b/gcc/testsuite/gcc.target/i386/pr35513-6.c new file mode 100644 index 00000000000..164899a96d0 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35513-6.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fplt -fno-pic -fsingle-global-definition" } */ + +extern void foo (void); + +void +bar (void) +{ + foo (); +} + +/* { dg-final { scan-assembler "jmp\[ \t\]*foo" } } */ +/* { dg-final { scan-assembler-not "foo@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "foo@GOT" { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr35513-7.c b/gcc/testsuite/gcc.target/i386/pr35513-7.c new file mode 100644 index 00000000000..5c6419368e7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35513-7.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fplt -fpic -fsingle-global-definition" } */ + +extern void foo (void); + +void +bar (void) +{ + foo (); +} + +/* { dg-final { scan-assembler "jmp\[ \t\]*foo@PLT" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler "call\[ \t\]*foo@PLT" { target ia32 } } } */ +/* { dg-final { scan-assembler-not "foo@GOTPCREL" { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "foo@GOT" { target ia32 } } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr35513-8.c b/gcc/testsuite/gcc.target/i386/pr35513-8.c new file mode 100644 index 00000000000..c0fef079d73 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35513-8.c @@ -0,0 +1,41 @@ +/* { dg-do assemble { target { *-*-linux* && { ! ia32 } } } } */ +/* { dg-require-effective-target maybe_x32 } */ +/* { dg-options "-mx32 -O2 -fno-pic -fexceptions -fasynchronous-unwind-tables -fsingle-global-definition" } */ + +extern int foo (int); +extern void exit (int __status) __attribute__ ((__nothrow__ )) __attribute__ ((__noreturn__)); +struct __pthread_cleanup_frame +{ + void (*__cancel_routine) (void *); + void *__cancel_arg; + int __do_it; + int __cancel_type; +}; +extern __inline void +__pthread_cleanup_routine (struct __pthread_cleanup_frame *__frame) +{ + if (__frame->__do_it) + __frame->__cancel_routine (__frame->__cancel_arg); +} +static int cl_called; + +static void +cl (void *arg) +{ + ++cl_called; +} + + +void * +tf_usleep (void *arg) +{ + + do { struct __pthread_cleanup_frame __clframe __attribute__ ((__cleanup__ (__pthread_cleanup_routine))) = { .__cancel_routine = (cl), .__cancel_arg = ( + ((void *)0)), .__do_it = 1 };; + + foo (arg == ((void *)0) ? (0x7fffffffL * 2UL + 1UL) : 0); + + __clframe.__do_it = (0); } while (0); + + exit (1); +} From patchwork Sun Jun 20 23:05:44 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: 1494831 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+incoming=patchwork.ozlabs.org@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=HWGgZQ3x; 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 4G7SyP4cG7z9sRN for ; Mon, 21 Jun 2021 09:08:45 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4F6EC385DC3D for ; Sun, 20 Jun 2021 23:08:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4F6EC385DC3D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1624230520; bh=1G0Z0W7mXRCO6upNlbBM9JNzlOhiYIuuZKP7NG8XoK4=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=HWGgZQ3x/oWnndNwH+HkAE1fDGIC8aAVG1AbbvvUAbtu183CutijvEjuXofKuxWXI pVtZpjFOgH4etJwzM3M9mCDDvxqdBsl4cM9MT5WXbDqk3ngc8cOGPGPSopYIPBn1Hz kjRw9qUpOsvidJVk6JWvvEa7EsZEN2WH90z6xEa8= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pf1-x434.google.com (mail-pf1-x434.google.com [IPv6:2607:f8b0:4864:20::434]) by sourceware.org (Postfix) with ESMTPS id F3909385743D for ; Sun, 20 Jun 2021 23:05:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org F3909385743D Received: by mail-pf1-x434.google.com with SMTP id a127so1676467pfa.10 for ; Sun, 20 Jun 2021 16:05:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1G0Z0W7mXRCO6upNlbBM9JNzlOhiYIuuZKP7NG8XoK4=; b=saMfDPncuGf1AjLmojsIcwPS+oDr0d6wI0TFbMxcTq4x6CbB9wxksm/nvcItDufgwo Aj9Yx3WyZHxn2DONgitJgr0AYJ7938PqvRv2RyFMu76v5dNlJkuZd6ttNJduFgwBcyBB J3XWLW18IfbTAmVlFYCP+DgM9n39k1fNLJIOH19hcdqLRNki/24S8XydcE/kKExB7R9d KfiA0I0BbQCSnBjrUKzEN3nEiAvFqxUjrcV9pXmT6L2wRiFWHipuF+KURoRMoO00252Y vRtqQALkbxSrPKF5kRk662nhqtZY//Va+0pv5ePcwUqvyjD/3/MHGv/ePKAVfeyR8oH1 OToQ== X-Gm-Message-State: AOAM5302kjMs8M2HHvxtEnuuXFf6nh6oYP5LV4rk3kHkgi/O2sW4mH/6 JVKfsvzV/+noiqQzpMbvGb5kPZFoq24= X-Google-Smtp-Source: ABdhPJyra2vWUwJ0yKpuynSmew5B8Wk+zIv4kwjj+SqcfAcZEj/x4iOSGElmYvjBNccBwEiyUTWzFw== X-Received: by 2002:aa7:9aae:0:b029:301:e3f5:7ad8 with SMTP id x14-20020aa79aae0000b0290301e3f57ad8mr7571229pfi.70.1624230346851; Sun, 20 Jun 2021 16:05:46 -0700 (PDT) Received: from gnu-cfl-2.localdomain ([172.56.39.115]) by smtp.gmail.com with ESMTPSA id u24sm14175696pfm.156.2021.06.20.16.05.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 20 Jun 2021 16:05:46 -0700 (PDT) Received: from gnu-cfl-2.. (localhost [IPv6:::1]) by gnu-cfl-2.localdomain (Postfix) with ESMTP id 7268DC056D; Sun, 20 Jun 2021 16:05:44 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH 2/2] Add TARGET_ASM_EMIT_GNU_PROPERTY_NOTE Date: Sun, 20 Jun 2021 16:05:44 -0700 Message-Id: <20210620230544.391025-3-hjl.tools@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210620230544.391025-1-hjl.tools@gmail.com> References: <20210620230544.391025-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_BARRACUDACENTRAL, 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" Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" Generate the GNU_PROPERTY_1_NEEDED_SINGLE_GLOBAL_DEFINITION marker for -fsingle-global-definition to indicate that the object file requires canonical function pointers and cannot be used with copy relocation. * configure.ac (HAVE_LD_SINGLE_GLOBAL_DEFINITION_SUPPORT): New. Define to 1 if linker supports -z single-global-definition. * 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 | 6 +++++ gcc/config/i386/gnu-property.c | 31 ---------------------- gcc/config/i386/i386.c | 2 ++ gcc/configure | 42 +++++++++++++++++++++++++++--- gcc/configure.ac | 20 +++++++++++++++ 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, 134 insertions(+), 34 deletions(-) diff --git a/gcc/config.in b/gcc/config.in index 18e627141cc..ee2a94f3847 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -1690,6 +1690,12 @@ #endif +/* Define to 1 if your linker supports -z single-global-definition */ +#ifndef USED_FOR_TARGET +#undef HAVE_LD_SINGLE_GLOBAL_DEFINITION_SUPPORT +#endif + + /* Define if your linker supports the *_sol2 emulations. */ #ifndef USED_FOR_TARGET #undef HAVE_LD_SOL2_EMULATION 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 9878c3126d0..b1268756322 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -24036,6 +24036,8 @@ ix86_run_selftests (void) #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 dd0194a57f4..3d53ce8cc9a 100755 --- a/gcc/configure +++ b/gcc/configure @@ -911,6 +911,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -1085,6 +1086,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' @@ -1337,6 +1339,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1474,7 +1485,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1627,6 +1638,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -19435,7 +19447,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 19438 "configure" +#line 19450 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -19541,7 +19553,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 19544 "configure" +#line 19556 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -32167,6 +32179,30 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_bndplt_support" >&5 $as_echo "$ld_bndplt_support" >&6; } +# Check linker supports '-z single-global-definition' +ld_single_global_definition=0 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker -z single-global-definition option" >&5 +$as_echo_n "checking linker -z single-global-definition option... " >&6; } +if test x"$ld_is_gold" = xno; then + if test $in_tree_ld = yes ; then + if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 37 -o "$gcc_cv_gld_major_version" -gt 2; then + ld_single_global_definition=1 + fi + elif test x$gcc_cv_ld != x; then + # Check if linker supports -z single-global-definition option + if $gcc_cv_ld --help 2>&1 | grep -- '-z single-global-definition' > /dev/null; then + ld_single_global_definition=1 + fi + fi +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_LD_SINGLE_GLOBAL_DEFINITION_SUPPORT $ld_single_global_definition +_ACEOF + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_single_global_definition" >&5 +$as_echo "$ld_single_global_definition" >&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 5f30f80833e..14ca4f450fa 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -7473,6 +7473,26 @@ if test x"$ld_bndplt_support" = xyes; then fi AC_MSG_RESULT($ld_bndplt_support) +# Check linker supports '-z single-global-definition' +ld_single_global_definition=0 +AC_MSG_CHECKING(linker -z single-global-definition option) +if test x"$ld_is_gold" = xno; then + if test $in_tree_ld = yes ; then + if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 37 -o "$gcc_cv_gld_major_version" -gt 2; then + ld_single_global_definition=1 + fi + elif test x$gcc_cv_ld != x; then + # Check if linker supports -z single-global-definition option + if $gcc_cv_ld --help 2>&1 | grep -- '-z single-global-definition' > /dev/null; then + ld_single_global_definition=1 + fi + fi +fi +AC_DEFINE_UNQUOTED(HAVE_LD_SINGLE_GLOBAL_DEFINITION_SUPPORT, + $ld_single_global_definition, + [Define to 1 if your linker supports -z single-global-definition]) +AC_MSG_RESULT($ld_single_global_definition) + # 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 2a41ae5fba1..5b1f5c135b0 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -8073,6 +8073,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 f881cdabe9e..7091e02ca81 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -5050,6 +5050,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 c009671c583..31e8bc0ab97 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 55e7550151f..bddcfdf5bde 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -585,6 +585,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 53cf6dea3f3..260b47131d8 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -7729,6 +7729,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_SINGLE_GLOBAL_DEFINITION_SUPPORT + && flag_single_global_definition) + /* Emite a GNU_PROPERTY_1_NEEDED note with + GNU_PROPERTY_1_NEEDED_SINGLE_GLOBAL_DEFINITION. */ + 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