From patchwork Fri Jul 9 14:50:13 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: 1503220 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=Ck8DKwiB; dkim-atps=neutral Received: from sourceware.org (ip-8-43-85-97.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 4GLx125WZgz9sRf for ; Sat, 10 Jul 2021 00:50:45 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7B907398CC2A for ; Fri, 9 Jul 2021 14:50:42 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7B907398CC2A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1625842242; bh=WGt5khFspUAR3tVWjiDD8s/L+PhAoHPqdL30wkQAgHA=; 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=Ck8DKwiBxeBhQtrnlyYZ6bFbM5tyIUqAyeRtixJ2oTgKcfI6WGKLGjGX6lowoYDcQ jGgR+FlwhGkak4YbIAGgZgssN9ywMgk4L7FwIkYfx7Ka8xJ6S2GXNyg3EIU/ZzHTcF gz/1F9R0zVMXY41R2dkboAvrVlhQqHg9Xxljokt8= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x630.google.com (mail-pl1-x630.google.com [IPv6:2607:f8b0:4864:20::630]) by sourceware.org (Postfix) with ESMTPS id 2A0223847802 for ; Fri, 9 Jul 2021 14:50:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2A0223847802 Received: by mail-pl1-x630.google.com with SMTP id p4so888649plo.11 for ; Fri, 09 Jul 2021 07:50:18 -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=WGt5khFspUAR3tVWjiDD8s/L+PhAoHPqdL30wkQAgHA=; b=Pid+PxPEiccvwRhT4MpXIqVN944urx2bW3srBTTotrRjYMsUYYtr77zd0CNSZsg1G8 QURJ6Pnj3i6aLHmJJzYkuW+k+Z63fPwjQWoIax079wuDb+RLCjiUUZ+w9dwncC30LLcv oRocK5Q43BI3+MI/nIMhXj6+OscwKt4ohol5ygZdBMfg8fOTX4f4qgQ5ruD1f2gs+3QH fjVCcKTBmtLreZEBYGw2OGvE0NVFGc0EQHrlzHi2NPxQw4oAiBis3h0EVp4ilp2YDkgN QuxBjK8MFE9xV7ftLaL8mouIgk9Y6d4ekNKpAZm/2/D4s3CmlfdiihIGZKjdSevCuMu/ /IJA== X-Gm-Message-State: AOAM530e112wjwWmm4DO/D/YPsOeU+tr0SsgdyxxQiV9lYqOiEGac42L zqewHIgbquOy9Rv/CPkHPFea3Fzg8es= X-Google-Smtp-Source: ABdhPJyeajQqPWC7D6cFRed78YlRWXh+qTTQt1SJzgliAO8dEZdUV03vuxtEeHP37HoQ/8KaJeMTVA== X-Received: by 2002:a17:90a:8589:: with SMTP id m9mr11191648pjn.168.1625842216951; Fri, 09 Jul 2021 07:50:16 -0700 (PDT) Received: from gnu-cfl-2.localdomain ([172.56.39.115]) by smtp.gmail.com with ESMTPSA id b2sm3943587pgh.9.2021.07.09.07.50.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Jul 2021 07:50:16 -0700 (PDT) Received: from gnu-cfl-2.. (localhost [IPv6:::1]) by gnu-cfl-2.localdomain (Postfix) with ESMTP id 79488C052F; Fri, 9 Jul 2021 07:50:14 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH v3 1/2] Add -f[no-]direct-extern-access Date: Fri, 9 Jul 2021 07:50:13 -0700 Message-Id: <20210709145014.1350564-2-hjl.tools@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210709145014.1350564-1-hjl.tools@gmail.com> References: <20210709145014.1350564-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3031.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_BARRACUDACENTRAL, 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: Jakub Jelinek Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" -fdirect-extern-access is the default. With -fno-direct-extern-access: 1. Always use GOT to access undefined data and function symbols, including in PIE and non-PIE. These will avoid copy relocations in executables. 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 or use executable PLT entries as function addresses for protected functions in shared libraries. 3. Update asm_preferred_eh_data_format to select PC relative EH encoding format with -fno-direct-extern-access to avoid copy relocation. 4. Add ix86_reloc_rw_mask for TARGET_ASM_RELOC_RW_MASK to avoid copy relocation with -fno-direct-extern-access. gcc/ PR target/35513 PR target/100593 * common.opt: Add -fdirect-extern-access. * 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 -fno-direct-extern-access. (legitimate_pic_address_disp_p): Avoid copy relocation in PIE for -fno-direct-extern-access. (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 -fno-direct-extern-access 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 with -fno-direct-extern-access. (ix86_reloc_rw_mask): New to avoid copy relocation for -fno-direct-extern-access. (TARGET_ASM_RELOC_RW_MASK): New. * doc/invoke.texi: Document -f[no-]direct-extern-access. 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 | 13 ++++++ 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, 278 insertions(+), 15 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 d9da1131eda..67ad811d54d 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1432,6 +1432,10 @@ fdiagnostics-minimum-margin-width= Common Joined UInteger Var(diagnostics_minimum_margin_width) Init(6) Set minimum width of left margin of source code when showing source. +fdirect-extern-access +Common Var(flag_direct_extern_access) Init(1) Optimization +Do not use GOT to access external symbols. + fdisable- Common Joined RejectNegative Var(common_deferred_options) Defer -fdisable-[tree|rtl|ipa]-=range1+range2 Disable an optimization pass. diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 51376fcc454..693cc3e5c78 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -79,7 +79,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 cff26909292..7dee311051d 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -10312,13 +10312,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: -fno-direct-extern-access 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 @@ -10326,11 +10330,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_direct_extern_access) + || (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)); } @@ -10596,7 +10601,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_direct_extern_access + && HAVE_LD_PIE_COPYRELOC && flag_pie && !SYMBOL_REF_WEAK (op0) && !SYMBOL_REF_FUNCTION_P (op0))) @@ -13498,7 +13504,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. */ @@ -21935,10 +21941,10 @@ int asm_preferred_eh_data_format (int code, int global) { /* PE-COFF is effectively always -fPIC because of the .reloc section. */ - if (flag_pic || TARGET_PECOFF) + if (flag_pic || TARGET_PECOFF || !flag_direct_extern_access) { 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; @@ -23028,10 +23034,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_direct_extern_access, + (flag_direct_extern_access + && (!flag_pic + || (TARGET_64BIT + && HAVE_LD_PIE_COPYRELOC != 0)))); +} + +/* If flag_pic or flag_direct_extern_access is false, then neither + local nor global relocs should be placed in readonly memory. */ + +static int +ix86_reloc_rw_mask (void) +{ + return (flag_pic || !flag_direct_extern_access) ? 3 : 0; } #endif @@ -24071,6 +24088,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 e67d47af676..2959c84cc3d 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -658,6 +658,7 @@ Objective-C and Objective-C++ Dialects}. -fnon-call-exceptions -fdelete-dead-exceptions -funwind-tables @gol -fasynchronous-unwind-tables @gol -fno-gnu-unique @gol +-fno-direct-extern-access @gol -finhibit-size-directive -fcommon -fno-ident @gol -fpcc-struct-return -fpic -fPIC -fpie -fPIE -fno-plt @gol -fno-jump-tables -fno-bit-tests @gol @@ -16633,6 +16634,18 @@ 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 -fno-direct-extern-access +@opindex fno-direct-extern-access +@opindex fdirect-extern-access +Without @option{-fpic} nor @option{-fPIC}, always use the GOT pointer +to access external symbols. With @option{-fpic} or @option{-fPIC}, +treat access to protected symbols as local symbols. + +@strong{Warning:} shared libraries compiled with +@option{-fno-direct-extern-access} and executable compiled with +@option{-fdirect-extern-access} may not be binary compatible if +protected symbols are used in shared libraries and executable. + @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..8423e826da8 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr35513-1.C @@ -0,0 +1,25 @@ +// { dg-do run } +// { dg-options "-O2 -fno-direct-extern-access" } + +#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..56ed19ae1eb --- /dev/null +++ b/gcc/testsuite/g++.dg/pr35513-2.C @@ -0,0 +1,53 @@ +// { dg-do run } +// { dg-options "-O2 -fno-direct-extern-access" } + +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..c5dbabc3704 --- /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 -fno-direct-extern-access" } */ + +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..8bb7cb4c13d --- /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 -fno-direct-extern-access" } */ + +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..98dc54e3bf4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35513-3.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-O2 -fpie -fno-direct-extern-access" } */ + +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..467081dad65 --- /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 -fno-direct-extern-access" } */ + +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..b0e61b08ba9 --- /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 -fno-direct-extern-access" } */ + +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..270504b8d0e --- /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 -fno-direct-extern-access" } */ + +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..2c5a83ddef8 --- /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 -fno-direct-extern-access" } */ + +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..545979e99c2 --- /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 -fno-direct-extern-access" } */ + +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 Fri Jul 9 14:50:14 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: 1503224 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=UuY8nhlf; 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 4GLx3k6J3gz9sRf for ; Sat, 10 Jul 2021 00:53:06 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C6850398CC20 for ; Fri, 9 Jul 2021 14:53:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C6850398CC20 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1625842383; bh=jnwvGFYG+Vs3ASegu9ftAGTBXNGTis05goIRHdsAefs=; 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=UuY8nhlfbbAfCObruywBIEevbLHLTo6zhJZH0dsyiyb5FXzbzrvdctBn0jCgMgK7M dYy668e5EANlJLSf1u8jESXh9YVmxZZGviIBDsiVZYv3DKX1mz2dCbUdcdBZ/KAJCo Dp4fF+jrS2pm0scxLmmKzzFC6B12Nk126eiO3oTo= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pf1-x42f.google.com (mail-pf1-x42f.google.com [IPv6:2607:f8b0:4864:20::42f]) by sourceware.org (Postfix) with ESMTPS id 8B29F3847813 for ; Fri, 9 Jul 2021 14:50:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8B29F3847813 Received: by mail-pf1-x42f.google.com with SMTP id y4so8893547pfi.9 for ; Fri, 09 Jul 2021 07:50:18 -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=jnwvGFYG+Vs3ASegu9ftAGTBXNGTis05goIRHdsAefs=; b=XlK2NpVySNFOrNt758uSms77uivuA6J2zjuGQJVpoZymSsffAG2a69jJkYoemdccni lx6pO13ImjMC8LSAxYh+J8Tr39J4Rs4wd3do/T9BOn355DC4vK29LvcM7mHLb8zmYBjO Um8sn6hv897KRavKj74Dqb9PQinkugDt1tk9bQgqZHe7aW/qz+leM/sivOjnu7EuJErr vDWrSdBlyuHcAQ5vGrhTBtpkyyLA0b2RqiqG6KufijdTP25/haihiQxI3iwu3pT/3k9H k+LYprQoCAiBKTubVy1+VIzWruiIMoYJPRMflPC2mnAf6hO5O7ll5pwnbyEPiMcrcYUn 3BMA== X-Gm-Message-State: AOAM533Kcn1eoi/FDsPAIzsrx72k4TrQK53Qv+1wuEMjyaGrsxfTOJCK 5JrWDGbGP9hyC4EBNy/INlo43bpfUbw= X-Google-Smtp-Source: ABdhPJy1Ozjegt3Fl82bhXZYXiXcyYf6B+WNlU8k9ukKXcLZHA9HHfTOxhraf2pMiu0Yd9V0sSl+tg== X-Received: by 2002:a05:6a00:1407:b029:30f:1f91:bdb0 with SMTP id l7-20020a056a001407b029030f1f91bdb0mr37551738pfu.24.1625842217145; Fri, 09 Jul 2021 07:50:17 -0700 (PDT) Received: from gnu-cfl-2.localdomain ([172.56.39.115]) by smtp.gmail.com with ESMTPSA id u2sm5945294pja.20.2021.07.09.07.50.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Jul 2021 07:50:16 -0700 (PDT) Received: from gnu-cfl-2.. (localhost [IPv6:::1]) by gnu-cfl-2.localdomain (Postfix) with ESMTP id 8426DC0563; Fri, 9 Jul 2021 07:50:14 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH v3 2/2] Add TARGET_ASM_EMIT_GNU_PROPERTY_NOTE Date: Fri, 9 Jul 2021 07:50:14 -0700 Message-Id: <20210709145014.1350564-3-hjl.tools@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210709145014.1350564-1-hjl.tools@gmail.com> References: <20210709145014.1350564-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3032.4 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.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: Jakub Jelinek Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.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. GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS support has been added to GNU binutils 2.38. But the -z indirect-extern-access linker option is only available for Linux/x86. However, the --max-cache-size=SIZE linker option was also addded within a day. --max-cache-size=SIZE is used to check for GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS support. 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 | 26 +++++++++++++++++++ gcc/configure.ac | 22 ++++++++++++++++ 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, 124 insertions(+), 31 deletions(-) diff --git a/gcc/config.in b/gcc/config.in index 2abac530c64..2c94a046de7 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -1652,6 +1652,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 7dee311051d..bd91c7cc7f8 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -24091,6 +24091,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 a15f8b47202..597b32b2959 100755 --- a/gcc/configure +++ b/gcc/configure @@ -32333,6 +32333,32 @@ 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 + 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 test x$gcc_cv_ld != x; then + # --max-cache-size=SIZE and GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS + # were added to GNU linker within a day. Check --max-cache-size=SIZE + # for GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS support. + if $gcc_cv_ld --help 2>&1 | grep -- '--max-cache-size=SIZE' > /dev/null; 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 26da07325e7..2058b126107 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -7575,6 +7575,28 @@ 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 + 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 test x$gcc_cv_ld != x; then + # --max-cache-size=SIZE and GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS + # were added to GNU linker within a day. Check --max-cache-size=SIZE + # for GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS support. + if $gcc_cv_ld --help 2>&1 | grep -- '--max-cache-size=SIZE' > /dev/null; 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 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 43f1f7d345e..a5c848cef22 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 53cf6dea3f3..b0850864534 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_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