diff mbox series

Add --enable-default-semantic-interposition to GCC configure

Message ID 20210606231215.49899-1-maskray@google.com
State New
Headers show
Series Add --enable-default-semantic-interposition to GCC configure | expand

Commit Message

Fangrui Song June 6, 2021, 11:12 p.m. UTC
From: Fangrui Song <i@maskray.me>

--enable-default-semantic-interposition=no makes -fPIC default to
-fno-semantic-interposition which enables interprocedural optimizations
for default visibility non-vague-linkage function definitions.

The suppression of interprocedural optimizations and inlining for such
functions is the biggest difference between -fPIE/-fPIC.
Distributions may want to enable default -fno-semantic-interposition to
reclaim the lost performance (e.g. CPython is said to be 27% faster;
Clang is 3% faster).

gcc/

    PR 100937
    * common.opt (fsemantic-interposition): Initialize to -1.
    * configure.ac: Add --enable-default-semantic-interposition. Default
    to yes.
    * defaults.h (DEFAULT_FLAG_SEMANTIC_INTERPOSITION): New.
    * opts.c (finish_options): Update
    opts->x_flag_semantic_interposition if it is -1.
    * doc/install.texi: Document --enable-default-semantic-interposition.
    * config.in: Add template.
    * configure: Regenerate.
---
 gcc/common.opt       |  2 +-
 gcc/config.in        |  6 ++++++
 gcc/configure        | 22 ++++++++++++++++++++--
 gcc/configure.ac     | 12 ++++++++++++
 gcc/defaults.h       |  6 ++++++
 gcc/doc/install.texi |  3 +++
 gcc/opts.c           |  3 +++
 7 files changed, 51 insertions(+), 3 deletions(-)

Comments

Andrew Pinski June 6, 2021, 11:18 p.m. UTC | #1
On Sun, Jun 6, 2021 at 4:13 PM Fangrui Song via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> From: Fangrui Song <i@maskray.me>
>
> --enable-default-semantic-interposition=no makes -fPIC default to
> -fno-semantic-interposition which enables interprocedural optimizations
> for default visibility non-vague-linkage function definitions.
>
> The suppression of interprocedural optimizations and inlining for such
> functions is the biggest difference between -fPIE/-fPIC.
> Distributions may want to enable default -fno-semantic-interposition to
> reclaim the lost performance (e.g. CPython is said to be 27% faster;
> Clang is 3% faster).


This breaks assumptions across the board.  If software packages want
to use -fno-semantic-interposition that is one thing.  But distros
should not be changing the default.  This is just like using
-ffast-math :).

Thanks,
Andrew Pinski

>
> gcc/
>
>     PR 100937
>     * common.opt (fsemantic-interposition): Initialize to -1.
>     * configure.ac: Add --enable-default-semantic-interposition. Default
>     to yes.
>     * defaults.h (DEFAULT_FLAG_SEMANTIC_INTERPOSITION): New.
>     * opts.c (finish_options): Update
>     opts->x_flag_semantic_interposition if it is -1.
>     * doc/install.texi: Document --enable-default-semantic-interposition.
>     * config.in: Add template.
>     * configure: Regenerate.
> ---
>  gcc/common.opt       |  2 +-
>  gcc/config.in        |  6 ++++++
>  gcc/configure        | 22 ++++++++++++++++++++--
>  gcc/configure.ac     | 12 ++++++++++++
>  gcc/defaults.h       |  6 ++++++
>  gcc/doc/install.texi |  3 +++
>  gcc/opts.c           |  3 +++
>  7 files changed, 51 insertions(+), 3 deletions(-)
>
> diff --git a/gcc/common.opt b/gcc/common.opt
> index ffb968d90f8..68fcbac96b1 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -2480,7 +2480,7 @@ Common Var(flag_sel_sched_reschedule_pipelined) Init(0) Optimization
>  Reschedule pipelined regions without pipelining.
>
>  fsemantic-interposition
> -Common Var(flag_semantic_interposition) Init(1)
> +Common Var(flag_semantic_interposition) Init(-1)
>  Allow interposing function (or variables) by ones with different semantics (or initializer) respectively by dynamic linker.
>
>  ; sched_stalled_insns means that insns can be moved prematurely from the queue
> diff --git a/gcc/config.in b/gcc/config.in
> index e54f59ce0c3..7f1d56c1903 100644
> --- a/gcc/config.in
> +++ b/gcc/config.in
> @@ -125,6 +125,12 @@
>  #endif
>
>
> +/* Define if -fPIC defaults to -fsemantic-interposition */
> +#ifndef USED_FOR_TARGET
> +#undef ENABLE_DEFAULT_SEMANTIC_INTERPOSITION
> +#endif
> +
> +
>  /* Define if your target supports default stack protector and it is enabled.
>     */
>  #ifndef USED_FOR_TARGET
> diff --git a/gcc/configure b/gcc/configure
> index 4a9e4fa08ab..3835b22f6a5 100755
> --- a/gcc/configure
> +++ b/gcc/configure
> @@ -632,6 +632,7 @@ ac_includes_default="\
>  ac_subst_vars='LTLIBOBJS
>  LIBOBJS
>  CET_HOST_FLAGS
> +enable_default_semantic_interposition
>  NO_PIE_FLAG
>  NO_PIE_CFLAGS
>  enable_default_pie
> @@ -1027,6 +1028,7 @@ with_linker_hash_style
>  with_diagnostics_color
>  with_diagnostics_urls
>  enable_default_pie
> +enable_default_semantic_interposition
>  enable_cet
>  enable_s390_excess_float_precision
>  '
> @@ -1787,6 +1789,8 @@ Optional Features:
>    --disable-libquadmath-support
>                            disable libquadmath support for Fortran
>    --enable-default-pie    enable Position Independent Executable as default
> +  --enable-default-semantic-interposition
> +                          enable -fsemantic-interposition as -fPIC default
>    --enable-cet            enable Intel CET in host libraries [default=auto]
>    --enable-s390-excess-float-precision
>                            on s390 targets, evaluate float with double
> @@ -19435,7 +19439,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 19454 "configure"
>  #include "confdefs.h"
>
>  #if HAVE_DLFCN_H
> @@ -19541,7 +19545,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 19560 "configure"
>  #include "confdefs.h"
>
>  #if HAVE_DLFCN_H
> @@ -31893,6 +31897,20 @@ if test "$gcc_cv_no_pie" = "yes"; then
>  fi
>
>
> +# Check whether --enable-default-semantic-interposition=no was given.
> +if test "${enable_default_semantic_interposition+set}" = set; then :
> +  enableval=$enable_default_semantic_interposition; enable_default_semantic_interposition=$enableval
> +else
> +  enable_default_semantic_interposition=yes
> +fi
> +
> +if test x$enable_default_semantic_interposition != xno ; then
> +
> +$as_echo "#define ENABLE_DEFAULT_SEMANTIC_INTERPOSITION 1" >>confdefs.h
> +
> +fi
> +
> +
>  # Enable Intel CET on Intel CET enabled host if jit is enabled.
>   # Check whether --enable-cet was given.
>  if test "${enable_cet+set}" = set; then :
> diff --git a/gcc/configure.ac b/gcc/configure.ac
> index d9fc3c219e8..1cdf8b4ce00 100644
> --- a/gcc/configure.ac
> +++ b/gcc/configure.ac
> @@ -7419,6 +7419,18 @@ if test "$gcc_cv_no_pie" = "yes"; then
>  fi
>  AC_SUBST([NO_PIE_FLAG])
>
> +# Check whether --enable-default-semantic-interposition=no was given.
> +AC_ARG_ENABLE(default-semantic-interposition,
> +[AS_HELP_STRING([--enable-default-semantic-interposition],
> +  [enable -fsemantic-interposition as -fPIC default])],
> +enable_default_semantic_interposition=$enableval,
> +enable_default_semantic_interposition=yes)
> +if test x$enable_default_semantic_interposition != xno ; then
> +  AC_DEFINE(ENABLE_DEFAULT_SEMANTIC_INTERPOSITION, 1,
> +      [Define if -fPIC defaults to -fsemantic-interposition.])
> +fi
> +AC_SUBST([enable_default_semantic_interposition])
> +
>  # Enable Intel CET on Intel CET enabled host if jit is enabled.
>  GCC_CET_HOST_FLAGS(CET_HOST_FLAGS)
>  case x$enable_languages in
> diff --git a/gcc/defaults.h b/gcc/defaults.h
> index 91216593e75..548b1f64f17 100644
> --- a/gcc/defaults.h
> +++ b/gcc/defaults.h
> @@ -1249,6 +1249,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>  # define DEFAULT_FLAG_PIE 0
>  #endif
>
> +#ifdef ENABLE_DEFAULT_SEMANTIC_INTERPOSITION
> +# define DEFAULT_FLAG_SEMANTIC_INTERPOSITION 1
> +#else
> +# define DEFAULT_FLAG_SEMANTIC_INTERPOSITION 0
> +#endif
> +
>  #ifndef SWITCHABLE_TARGET
>  #define SWITCHABLE_TARGET 0
>  #endif
> diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
> index 591ccaacbc1..17e756c7e7a 100644
> --- a/gcc/doc/install.texi
> +++ b/gcc/doc/install.texi
> @@ -1867,6 +1867,9 @@ mips-linux and s390-linux.
>  @item --enable-default-pie
>  Turn on @option{-fPIE} and @option{-pie} by default.
>
> +@item --enable-default-semantic-interposition=no
> +Make @option{-fPIC} default to @option{-fno-semantic-interposition}.
> +
>  @item --enable-secureplt
>  This option enables @option{-msecure-plt} by default for powerpc-linux.
>  @ifnothtml
> diff --git a/gcc/opts.c b/gcc/opts.c
> index a751d95d32b..c6f49af2583 100644
> --- a/gcc/opts.c
> +++ b/gcc/opts.c
> @@ -1068,6 +1068,9 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
>    if (opts->x_flag_stack_protect == -1)
>      opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
>
> +  if (opts->x_flag_semantic_interposition == -1)
> +    opts->x_flag_semantic_interposition = DEFAULT_FLAG_SEMANTIC_INTERPOSITION;
> +
>    if (opts->x_optimize == 0)
>      {
>        /* Inlining does not work if not optimizing,
> --
> 2.32.0.rc1.229.g3e70b5a671-goog
>
Fangrui Song June 6, 2021, 11:36 p.m. UTC | #2
On 2021-06-06, Andrew Pinski wrote:
>On Sun, Jun 6, 2021 at 4:13 PM Fangrui Song via Gcc-patches
><gcc-patches@gcc.gnu.org> wrote:
>>
>> From: Fangrui Song <i@maskray.me>
>>
>> --enable-default-semantic-interposition=no makes -fPIC default to
>> -fno-semantic-interposition which enables interprocedural optimizations
>> for default visibility non-vague-linkage function definitions.
>>
>> The suppression of interprocedural optimizations and inlining for such
>> functions is the biggest difference between -fPIE/-fPIC.
>> Distributions may want to enable default -fno-semantic-interposition to
>> reclaim the lost performance (e.g. CPython is said to be 27% faster;
>> Clang is 3% faster).
>
>
>This breaks assumptions across the board.  If software packages want
>to use -fno-semantic-interposition that is one thing.  But distros
>should not be changing the default.  This is just like using
>-ffast-math :).
>
>Thanks,
>Andrew Pinski

What assumption?

Vague linkage function definitions already support IPO/inlining.

For a large non-vague linkage function, presumably GCC will not inline
it into the call sites in the same TU, users can keep using LD_PRELOAD
to interpose that single symbol.

Even if the non-vague function is small and inlined, users can use LD_PRELOAD to
interpose both the callee and callers.

You cannot do such interposition for Windows.
macOS two-level namespace requires explicit `ld -flat_interpose` for such definition interposition.
Users are free to add noinline or -fsemantic-interposition.


>> gcc/
>>
>>     PR 100937
>>     * common.opt (fsemantic-interposition): Initialize to -1.
>>     * configure.ac: Add --enable-default-semantic-interposition. Default
>>     to yes.
>>     * defaults.h (DEFAULT_FLAG_SEMANTIC_INTERPOSITION): New.
>>     * opts.c (finish_options): Update
>>     opts->x_flag_semantic_interposition if it is -1.
>>     * doc/install.texi: Document --enable-default-semantic-interposition.
>>     * config.in: Add template.
>>     * configure: Regenerate.
>> ---
>>  gcc/common.opt       |  2 +-
>>  gcc/config.in        |  6 ++++++
>>  gcc/configure        | 22 ++++++++++++++++++++--
>>  gcc/configure.ac     | 12 ++++++++++++
>>  gcc/defaults.h       |  6 ++++++
>>  gcc/doc/install.texi |  3 +++
>>  gcc/opts.c           |  3 +++
>>  7 files changed, 51 insertions(+), 3 deletions(-)
>>
>> diff --git a/gcc/common.opt b/gcc/common.opt
>> index ffb968d90f8..68fcbac96b1 100644
>> --- a/gcc/common.opt
>> +++ b/gcc/common.opt
>> @@ -2480,7 +2480,7 @@ Common Var(flag_sel_sched_reschedule_pipelined) Init(0) Optimization
>>  Reschedule pipelined regions without pipelining.
>>
>>  fsemantic-interposition
>> -Common Var(flag_semantic_interposition) Init(1)
>> +Common Var(flag_semantic_interposition) Init(-1)
>>  Allow interposing function (or variables) by ones with different semantics (or initializer) respectively by dynamic linker.
>>
>>  ; sched_stalled_insns means that insns can be moved prematurely from the queue
>> diff --git a/gcc/config.in b/gcc/config.in
>> index e54f59ce0c3..7f1d56c1903 100644
>> --- a/gcc/config.in
>> +++ b/gcc/config.in
>> @@ -125,6 +125,12 @@
>>  #endif
>>
>>
>> +/* Define if -fPIC defaults to -fsemantic-interposition */
>> +#ifndef USED_FOR_TARGET
>> +#undef ENABLE_DEFAULT_SEMANTIC_INTERPOSITION
>> +#endif
>> +
>> +
>>  /* Define if your target supports default stack protector and it is enabled.
>>     */
>>  #ifndef USED_FOR_TARGET
>> diff --git a/gcc/configure b/gcc/configure
>> index 4a9e4fa08ab..3835b22f6a5 100755
>> --- a/gcc/configure
>> +++ b/gcc/configure
>> @@ -632,6 +632,7 @@ ac_includes_default="\
>>  ac_subst_vars='LTLIBOBJS
>>  LIBOBJS
>>  CET_HOST_FLAGS
>> +enable_default_semantic_interposition
>>  NO_PIE_FLAG
>>  NO_PIE_CFLAGS
>>  enable_default_pie
>> @@ -1027,6 +1028,7 @@ with_linker_hash_style
>>  with_diagnostics_color
>>  with_diagnostics_urls
>>  enable_default_pie
>> +enable_default_semantic_interposition
>>  enable_cet
>>  enable_s390_excess_float_precision
>>  '
>> @@ -1787,6 +1789,8 @@ Optional Features:
>>    --disable-libquadmath-support
>>                            disable libquadmath support for Fortran
>>    --enable-default-pie    enable Position Independent Executable as default
>> +  --enable-default-semantic-interposition
>> +                          enable -fsemantic-interposition as -fPIC default
>>    --enable-cet            enable Intel CET in host libraries [default=auto]
>>    --enable-s390-excess-float-precision
>>                            on s390 targets, evaluate float with double
>> @@ -19435,7 +19439,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 19454 "configure"
>>  #include "confdefs.h"
>>
>>  #if HAVE_DLFCN_H
>> @@ -19541,7 +19545,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 19560 "configure"
>>  #include "confdefs.h"
>>
>>  #if HAVE_DLFCN_H
>> @@ -31893,6 +31897,20 @@ if test "$gcc_cv_no_pie" = "yes"; then
>>  fi
>>
>>
>> +# Check whether --enable-default-semantic-interposition=no was given.
>> +if test "${enable_default_semantic_interposition+set}" = set; then :
>> +  enableval=$enable_default_semantic_interposition; enable_default_semantic_interposition=$enableval
>> +else
>> +  enable_default_semantic_interposition=yes
>> +fi
>> +
>> +if test x$enable_default_semantic_interposition != xno ; then
>> +
>> +$as_echo "#define ENABLE_DEFAULT_SEMANTIC_INTERPOSITION 1" >>confdefs.h
>> +
>> +fi
>> +
>> +
>>  # Enable Intel CET on Intel CET enabled host if jit is enabled.
>>   # Check whether --enable-cet was given.
>>  if test "${enable_cet+set}" = set; then :
>> diff --git a/gcc/configure.ac b/gcc/configure.ac
>> index d9fc3c219e8..1cdf8b4ce00 100644
>> --- a/gcc/configure.ac
>> +++ b/gcc/configure.ac
>> @@ -7419,6 +7419,18 @@ if test "$gcc_cv_no_pie" = "yes"; then
>>  fi
>>  AC_SUBST([NO_PIE_FLAG])
>>
>> +# Check whether --enable-default-semantic-interposition=no was given.
>> +AC_ARG_ENABLE(default-semantic-interposition,
>> +[AS_HELP_STRING([--enable-default-semantic-interposition],
>> +  [enable -fsemantic-interposition as -fPIC default])],
>> +enable_default_semantic_interposition=$enableval,
>> +enable_default_semantic_interposition=yes)
>> +if test x$enable_default_semantic_interposition != xno ; then
>> +  AC_DEFINE(ENABLE_DEFAULT_SEMANTIC_INTERPOSITION, 1,
>> +      [Define if -fPIC defaults to -fsemantic-interposition.])
>> +fi
>> +AC_SUBST([enable_default_semantic_interposition])
>> +
>>  # Enable Intel CET on Intel CET enabled host if jit is enabled.
>>  GCC_CET_HOST_FLAGS(CET_HOST_FLAGS)
>>  case x$enable_languages in
>> diff --git a/gcc/defaults.h b/gcc/defaults.h
>> index 91216593e75..548b1f64f17 100644
>> --- a/gcc/defaults.h
>> +++ b/gcc/defaults.h
>> @@ -1249,6 +1249,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>>  # define DEFAULT_FLAG_PIE 0
>>  #endif
>>
>> +#ifdef ENABLE_DEFAULT_SEMANTIC_INTERPOSITION
>> +# define DEFAULT_FLAG_SEMANTIC_INTERPOSITION 1
>> +#else
>> +# define DEFAULT_FLAG_SEMANTIC_INTERPOSITION 0
>> +#endif
>> +
>>  #ifndef SWITCHABLE_TARGET
>>  #define SWITCHABLE_TARGET 0
>>  #endif
>> diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
>> index 591ccaacbc1..17e756c7e7a 100644
>> --- a/gcc/doc/install.texi
>> +++ b/gcc/doc/install.texi
>> @@ -1867,6 +1867,9 @@ mips-linux and s390-linux.
>>  @item --enable-default-pie
>>  Turn on @option{-fPIE} and @option{-pie} by default.
>>
>> +@item --enable-default-semantic-interposition=no
>> +Make @option{-fPIC} default to @option{-fno-semantic-interposition}.
>> +
>>  @item --enable-secureplt
>>  This option enables @option{-msecure-plt} by default for powerpc-linux.
>>  @ifnothtml
>> diff --git a/gcc/opts.c b/gcc/opts.c
>> index a751d95d32b..c6f49af2583 100644
>> --- a/gcc/opts.c
>> +++ b/gcc/opts.c
>> @@ -1068,6 +1068,9 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
>>    if (opts->x_flag_stack_protect == -1)
>>      opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
>>
>> +  if (opts->x_flag_semantic_interposition == -1)
>> +    opts->x_flag_semantic_interposition = DEFAULT_FLAG_SEMANTIC_INTERPOSITION;
>> +
>>    if (opts->x_optimize == 0)
>>      {
>>        /* Inlining does not work if not optimizing,
>> --
>> 2.32.0.rc1.229.g3e70b5a671-goog
>>
Jeff Law June 7, 2021, 6:01 p.m. UTC | #3
On 6/6/2021 5:18 PM, Andrew Pinski via Gcc-patches wrote:
> On Sun, Jun 6, 2021 at 4:13 PM Fangrui Song via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
>> From: Fangrui Song <i@maskray.me>
>>
>> --enable-default-semantic-interposition=no makes -fPIC default to
>> -fno-semantic-interposition which enables interprocedural optimizations
>> for default visibility non-vague-linkage function definitions.
>>
>> The suppression of interprocedural optimizations and inlining for such
>> functions is the biggest difference between -fPIE/-fPIC.
>> Distributions may want to enable default -fno-semantic-interposition to
>> reclaim the lost performance (e.g. CPython is said to be 27% faster;
>> Clang is 3% faster).
>
> This breaks assumptions across the board.  If software packages want
> to use -fno-semantic-interposition that is one thing.  But distros
> should not be changing the default.  This is just like using
> -ffast-math :).
Some distros already force immediate binding at link time for security 
purposes on a distro-wide basis which, IIUC, does the same thing, but 
without the benefits from a code generation standpoint.

Jeff
Jakub Jelinek June 7, 2021, 6:13 p.m. UTC | #4
On Mon, Jun 07, 2021 at 12:01:55PM -0600, Jeff Law via Gcc-patches wrote:
> > This breaks assumptions across the board.  If software packages want
> > to use -fno-semantic-interposition that is one thing.  But distros
> > should not be changing the default.  This is just like using
> > -ffast-math :).
> Some distros already force immediate binding at link time for security
> purposes on a distro-wide basis which, IIUC, does the same thing, but
> without the benefits from a code generation standpoint.

If you are talking about -Wl,-z,now, that is very different, semantic
interposition then still works just fine.
If you are talking about the glibc style by hand "protected" visibility,
bind calls to symbols defined in the same library through internal symbols,
then that is done only for a couple of packages and is stronger than
-fno-semantic-interposition.

	Jakub
Fangrui Song June 7, 2021, 7:01 p.m. UTC | #5
On 2021-06-07, Jakub Jelinek wrote:
>On Mon, Jun 07, 2021 at 12:01:55PM -0600, Jeff Law via Gcc-patches wrote:
>> > This breaks assumptions across the board.  If software packages want
>> > to use -fno-semantic-interposition that is one thing.  But distros
>> > should not be changing the default.  This is just like using
>> > -ffast-math :).
>> Some distros already force immediate binding at link time for security
>> purposes on a distro-wide basis which, IIUC, does the same thing, but
>> without the benefits from a code generation standpoint.
>
>If you are talking about -Wl,-z,now, that is very different, semantic
>interposition then still works just fine.
>If you are talking about the glibc style by hand "protected" visibility,
>bind calls to symbols defined in the same library through internal symbols,
>then that is done only for a couple of packages and is stronger than
>-fno-semantic-interposition.
>
>	Jakub
>

-fno-semantic-interposition can save a PLT entry (and associated
R_*_JUMP_SLOT dynamic relocation) if a default visibility STB_GLOBAL
function is only called in its defining TU, not by other TUs linked into
the shared object.

This is a subset of the PLT-suppressing optimization if a distribution defaults to ld -Bsymbolic-non-weak-functions
(https://maskray.me/blog/2021-05-16-elf-interposition-and-bsymbolic#the-last-alliance-of-elf-and-men)



Binding definitions in the same component can make software securer.

https://twitter.com/CarlosODonell/status/1400879768028028935
"Disable PRELOAD/AUDIT, which is what I'm going to pursue e.g.  system-wide glibc hardening tunable."
If such a thing is deployed, why cannot a passionate distribution default to gcc -fno-semantic-interposition  and ld -Bsymbolic-non-weak-functions
can bring back the lost performance (15+% for my clang; 27% for cpython; ...)



Last, the "assumption" is just GCC's mapping from source code to the ELF binary
format.
https://maskray.me/blog/2021-05-09-fno-semantic-interposition#source-level-implication
We could also argue that C++ odr rule doesn't like us doing semantic interposition.
(I know it's vague https://stackoverflow.com/questions/55632222/odr-violation-when-linking-static-and-dynamic-library )
diff mbox series

Patch

diff --git a/gcc/common.opt b/gcc/common.opt
index ffb968d90f8..68fcbac96b1 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2480,7 +2480,7 @@  Common Var(flag_sel_sched_reschedule_pipelined) Init(0) Optimization
 Reschedule pipelined regions without pipelining.
 
 fsemantic-interposition
-Common Var(flag_semantic_interposition) Init(1)
+Common Var(flag_semantic_interposition) Init(-1)
 Allow interposing function (or variables) by ones with different semantics (or initializer) respectively by dynamic linker.
 
 ; sched_stalled_insns means that insns can be moved prematurely from the queue
diff --git a/gcc/config.in b/gcc/config.in
index e54f59ce0c3..7f1d56c1903 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -125,6 +125,12 @@ 
 #endif
 
 
+/* Define if -fPIC defaults to -fsemantic-interposition */
+#ifndef USED_FOR_TARGET
+#undef ENABLE_DEFAULT_SEMANTIC_INTERPOSITION
+#endif
+
+
 /* Define if your target supports default stack protector and it is enabled.
    */
 #ifndef USED_FOR_TARGET
diff --git a/gcc/configure b/gcc/configure
index 4a9e4fa08ab..3835b22f6a5 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -632,6 +632,7 @@  ac_includes_default="\
 ac_subst_vars='LTLIBOBJS
 LIBOBJS
 CET_HOST_FLAGS
+enable_default_semantic_interposition
 NO_PIE_FLAG
 NO_PIE_CFLAGS
 enable_default_pie
@@ -1027,6 +1028,7 @@  with_linker_hash_style
 with_diagnostics_color
 with_diagnostics_urls
 enable_default_pie
+enable_default_semantic_interposition
 enable_cet
 enable_s390_excess_float_precision
 '
@@ -1787,6 +1789,8 @@  Optional Features:
   --disable-libquadmath-support
                           disable libquadmath support for Fortran
   --enable-default-pie    enable Position Independent Executable as default
+  --enable-default-semantic-interposition
+                          enable -fsemantic-interposition as -fPIC default
   --enable-cet            enable Intel CET in host libraries [default=auto]
   --enable-s390-excess-float-precision
                           on s390 targets, evaluate float with double
@@ -19435,7 +19439,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 19454 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -19541,7 +19545,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 19560 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -31893,6 +31897,20 @@  if test "$gcc_cv_no_pie" = "yes"; then
 fi
 
 
+# Check whether --enable-default-semantic-interposition=no was given.
+if test "${enable_default_semantic_interposition+set}" = set; then :
+  enableval=$enable_default_semantic_interposition; enable_default_semantic_interposition=$enableval
+else
+  enable_default_semantic_interposition=yes
+fi
+
+if test x$enable_default_semantic_interposition != xno ; then
+
+$as_echo "#define ENABLE_DEFAULT_SEMANTIC_INTERPOSITION 1" >>confdefs.h
+
+fi
+
+
 # Enable Intel CET on Intel CET enabled host if jit is enabled.
  # Check whether --enable-cet was given.
 if test "${enable_cet+set}" = set; then :
diff --git a/gcc/configure.ac b/gcc/configure.ac
index d9fc3c219e8..1cdf8b4ce00 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -7419,6 +7419,18 @@  if test "$gcc_cv_no_pie" = "yes"; then
 fi
 AC_SUBST([NO_PIE_FLAG])
 
+# Check whether --enable-default-semantic-interposition=no was given.
+AC_ARG_ENABLE(default-semantic-interposition,
+[AS_HELP_STRING([--enable-default-semantic-interposition],
+  [enable -fsemantic-interposition as -fPIC default])],
+enable_default_semantic_interposition=$enableval,
+enable_default_semantic_interposition=yes)
+if test x$enable_default_semantic_interposition != xno ; then
+  AC_DEFINE(ENABLE_DEFAULT_SEMANTIC_INTERPOSITION, 1,
+      [Define if -fPIC defaults to -fsemantic-interposition.])
+fi
+AC_SUBST([enable_default_semantic_interposition])
+
 # Enable Intel CET on Intel CET enabled host if jit is enabled.
 GCC_CET_HOST_FLAGS(CET_HOST_FLAGS)
 case x$enable_languages in
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 91216593e75..548b1f64f17 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -1249,6 +1249,12 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 # define DEFAULT_FLAG_PIE 0
 #endif
 
+#ifdef ENABLE_DEFAULT_SEMANTIC_INTERPOSITION
+# define DEFAULT_FLAG_SEMANTIC_INTERPOSITION 1
+#else
+# define DEFAULT_FLAG_SEMANTIC_INTERPOSITION 0
+#endif
+
 #ifndef SWITCHABLE_TARGET
 #define SWITCHABLE_TARGET 0
 #endif
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 591ccaacbc1..17e756c7e7a 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -1867,6 +1867,9 @@  mips-linux and s390-linux.
 @item --enable-default-pie
 Turn on @option{-fPIE} and @option{-pie} by default.
 
+@item --enable-default-semantic-interposition=no
+Make @option{-fPIC} default to @option{-fno-semantic-interposition}.
+
 @item --enable-secureplt
 This option enables @option{-msecure-plt} by default for powerpc-linux.
 @ifnothtml
diff --git a/gcc/opts.c b/gcc/opts.c
index a751d95d32b..c6f49af2583 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1068,6 +1068,9 @@  finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
   if (opts->x_flag_stack_protect == -1)
     opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
 
+  if (opts->x_flag_semantic_interposition == -1)
+    opts->x_flag_semantic_interposition = DEFAULT_FLAG_SEMANTIC_INTERPOSITION;
+
   if (opts->x_optimize == 0)
     {
       /* Inlining does not work if not optimizing,