On Sun, Jul 11, 2021 at 11:13 PM Richard Biener
<richard.guent...@gmail.com> wrote:
>
> On Fri, Jul 9, 2021 at 4:50 PM H.J. Lu <hjl.to...@gmail.com> wrote:
> >
> > -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.
>
> Did you check how relocations in .debug_info behave?  I don't remember whether

Yes, I did.   I added ix86_reloc_rw_mask and use PC-relative format for
EH pointer encodings to avoid copy relocation for -fno-direct-extern-access
in read-only sections.

> we're doing anything special there or if we just copy how we emit
> relocs in .text
>
> Richard.
>
> > 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]-<pass>=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 <iostream>
> > +
> > +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);
> > +}
> > --
> > 2.31.1
> >



-- 
H.J.

Reply via email to