[PATCH] gold: Add -Bsymbolic-non-weak-functions
Fangrui Song
i@maskray.me
Wed May 26 23:22:46 GMT 2021
On Wed, May 19, 2021 at 11:05 PM Fangrui Song via Binutils
<binutils@sourceware.org> wrote:
>
> This option is a subset of -Bsymbolic-functions: only STB_GLOBAL are
> considered. Vague linkage functions are STB_WEAK. A vague linkage
> function may have different addresses in a -Bsymbolic-functions linked
> shared object and outside the shared object.
> -Bsymbolic-non-weak-functions can keep pointer equality while providing
> most benefits: (a) fewer JUMP_SLOT (symbol lookups) (b) avoid PLT
> entries for default visibility defined functions.
>
> [Hope a maintainer can implement this for GNU ld.
> The code is too difficult for me to implement:)]
>
> gold/
> PR 27871
> * options.h (General_options): Add -Bsymbolic-non-weak-functions.
> * options.cc (General_options): Define
> parse_Bsymbols_non_weak_functions.
> * symtab.h (Symbol::is_preemptible): Check -Bsymbolic-non-weak-functions.
> * testsuite/Makefile.am (check_SCRIPTS): Add bsymbolic_non_weak_functions.sh.
> (check_DATA): Add bsymbolic_non_weak_functions.stdout.
> (MOSTLYCLEANFILES): Add bsymbolic_non_weak_functions.
> * testsuite/Makefile.in: Regenerate.
> * testsuite/bsymbolic_non_weak_functions.sh: New file.
> * testsuite/bsymbolic_non_weak_functions.c: New file.
> ---
> gold/options.cc | 7 +++
> gold/options.h | 10 ++++
> gold/symtab.h | 4 +-
> gold/testsuite/Makefile.am | 10 ++++
> gold/testsuite/Makefile.in | 22 +++++++--
> gold/testsuite/bsymbolic_non_weak_functions.c | 46 +++++++++++++++++++
> .../testsuite/bsymbolic_non_weak_functions.sh | 46 +++++++++++++++++++
> 7 files changed, 141 insertions(+), 4 deletions(-)
> create mode 100644 gold/testsuite/bsymbolic_non_weak_functions.c
> create mode 100755 gold/testsuite/bsymbolic_non_weak_functions.sh
>
> diff --git a/gold/options.cc b/gold/options.cc
> index 5a55bd8ba6d..2335dbccc03 100644
> --- a/gold/options.cc
> +++ b/gold/options.cc
> @@ -347,6 +347,13 @@ General_options::parse_Bno_symbolic(const char*, const char*,
> this->bsymbolic_ = BSYMBOLIC_NONE;
> }
>
> +void
> +General_options::parse_Bsymbolic_non_weak_functions(const char*, const char*,
> + Command_line*)
> +{
> + this->bsymbolic_ = BSYMBOLIC_NON_WEAK_FUNCTIONS;
> +}
> +
> void
> General_options::parse_Bsymbolic_functions(const char*, const char*,
> Command_line*)
> diff --git a/gold/options.h b/gold/options.h
> index 757ebf18fec..b14503ce23f 100644
> --- a/gold/options.h
> +++ b/gold/options.h
> @@ -752,6 +752,11 @@ class General_options
> "for -shared (default)"),
> NULL);
>
> + DEFINE_special (Bsymbolic_non_weak_functions, options::ONE_DASH, '\0',
> + N_ ("Bind default visibility defined STB_GLOBAL function symbols "
> + "locally for -shared"),
> + NULL);
> +
> DEFINE_special (Bsymbolic_functions, options::ONE_DASH, '\0',
> N_ ("Bind default visibility defined function symbols "
> "locally for -shared"),
> @@ -1752,6 +1757,7 @@ class General_options
> enum Bsymbolic_kind
> {
> BSYMBOLIC_NONE,
> + BSYMBOLIC_NON_WEAK_FUNCTIONS,
> BSYMBOLIC_FUNCTIONS,
> BSYMBOLIC_ALL,
> };
> @@ -1760,6 +1766,10 @@ class General_options
> Bsymbolic() const
> { return this->bsymbolic_ == BSYMBOLIC_ALL; }
>
> + bool
> + Bsymbolic_non_weak_functions() const
> + { return this->bsymbolic_ == BSYMBOLIC_NON_WEAK_FUNCTIONS; }
> +
> bool
> Bsymbolic_functions() const
> { return this->bsymbolic_ == BSYMBOLIC_FUNCTIONS; }
> diff --git a/gold/symtab.h b/gold/symtab.h
> index 104429a5af1..b1dce1961bb 100644
> --- a/gold/symtab.h
> +++ b/gold/symtab.h
> @@ -628,7 +628,9 @@ class Symbol
> // rather than for being STT_FUNC, because that is what the GNU
> // linker does.
> if (this->type() != elfcpp::STT_OBJECT
> - && parameters->options().Bsymbolic_functions())
> + && (parameters->options().Bsymbolic_functions()
> + || (parameters->options().Bsymbolic_non_weak_functions()
> + && this->binding() != elfcpp::STB_WEAK)))
> return false;
>
> // Otherwise the symbol is preemptible.
> diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
> index 38e54818f48..bea11a0675e 100644
> --- a/gold/testsuite/Makefile.am
> +++ b/gold/testsuite/Makefile.am
> @@ -4434,4 +4434,14 @@ retain_2: retain_2.o ../ld-new
> retain_2.o: retain_2.s
> $(TEST_AS) -o $@ $<
>
> +check_SCRIPTS += bsymbolic_non_weak_functions.sh
> +check_DATA += bsymbolic_non_weak_functions.stdout
> +MOSTLYCLEANFILES += bsymbolic_non_weak_functions
> +bsymbolic_non_weak_functions: bsymbolic_non_weak_functions.o gcctestdir/ld
> + $(CXXLINK) $< -shared -Wl,-Bsymbolic-non-weak-functions
> +bsymbolic_non_weak_functions.o: bsymbolic_non_weak_functions.c
> + $(COMPILE) -c -fpic -o $@ $<
> +bsymbolic_non_weak_functions.stdout: bsymbolic_non_weak_functions
> + $(TEST_READELF) -rW $< > $@
> +
> endif DEFAULT_TARGET_X86_64
> diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in
> index 7b4b7832d38..792e4cd63e7 100644
> --- a/gold/testsuite/Makefile.in
> +++ b/gold/testsuite/Makefile.in
> @@ -1130,13 +1130,16 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
> @DEFAULT_TARGET_S390_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ split_s390x_z4_ns split_s390x_n1_ns split_s390x_n2_ns split_s390x_r
>
> @DEFAULT_TARGET_X86_64_TRUE@am__append_114 = *.dwo *.dwp pr26936a \
> -@DEFAULT_TARGET_X86_64_TRUE@ pr26936b retain_1 retain_2
> +@DEFAULT_TARGET_X86_64_TRUE@ pr26936b retain_1 retain_2 \
> +@DEFAULT_TARGET_X86_64_TRUE@ bsymbolic_non_weak_functions
> @DEFAULT_TARGET_X86_64_TRUE@am__append_115 = dwp_test_1.sh \
> -@DEFAULT_TARGET_X86_64_TRUE@ dwp_test_2.sh pr26936.sh retain.sh
> +@DEFAULT_TARGET_X86_64_TRUE@ dwp_test_2.sh pr26936.sh retain.sh \
> +@DEFAULT_TARGET_X86_64_TRUE@ bsymbolic_non_weak_functions.sh
> @DEFAULT_TARGET_X86_64_TRUE@am__append_116 = dwp_test_1.stdout \
> @DEFAULT_TARGET_X86_64_TRUE@ dwp_test_2.stdout pr26936a.stdout \
> @DEFAULT_TARGET_X86_64_TRUE@ pr26936b.stdout retain_1.out \
> -@DEFAULT_TARGET_X86_64_TRUE@ retain_2.out
> +@DEFAULT_TARGET_X86_64_TRUE@ retain_2.out \
> +@DEFAULT_TARGET_X86_64_TRUE@ bsymbolic_non_weak_functions.stdout
> subdir = testsuite
> ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
> am__aclocal_m4_deps = $(top_srcdir)/../config/ax_pthread.m4 \
> @@ -6459,6 +6462,13 @@ retain.sh.log: retain.sh
> --log-file $$b.log --trs-file $$b.trs \
> $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
> "$$tst" $(AM_TESTS_FD_REDIRECT)
> +bsymbolic_non_weak_functions.sh.log: bsymbolic_non_weak_functions.sh
> + @p='bsymbolic_non_weak_functions.sh'; \
> + b='bsymbolic_non_weak_functions.sh'; \
> + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
> + --log-file $$b.log --trs-file $$b.trs \
> + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
> + "$$tst" $(AM_TESTS_FD_REDIRECT)
> object_unittest.log: object_unittest$(EXEEXT)
> @p='object_unittest$(EXEEXT)'; \
> b='object_unittest'; \
> @@ -10414,6 +10424,12 @@ uninstall-am:
> @DEFAULT_TARGET_X86_64_TRUE@ ../ld-new -pie -e _start --gc-sections -o $@ retain_2.o
> @DEFAULT_TARGET_X86_64_TRUE@retain_2.o: retain_2.s
> @DEFAULT_TARGET_X86_64_TRUE@ $(TEST_AS) -o $@ $<
> +@DEFAULT_TARGET_X86_64_TRUE@bsymbolic_non_weak_functions: bsymbolic_non_weak_functions.o gcctestdir/ld
> +@DEFAULT_TARGET_X86_64_TRUE@ $(CXXLINK) $< -shared -Wl,-Bsymbolic-non-weak-functions
> +@DEFAULT_TARGET_X86_64_TRUE@bsymbolic_non_weak_functions.o: bsymbolic_non_weak_functions.c
> +@DEFAULT_TARGET_X86_64_TRUE@ $(COMPILE) -c -fpic -o $@ $<
> +@DEFAULT_TARGET_X86_64_TRUE@bsymbolic_non_weak_functions.stdout: bsymbolic_non_weak_functions
> +@DEFAULT_TARGET_X86_64_TRUE@ $(TEST_READELF) -rW $< > $@
>
> # Tell versions [3.59,3.63) of GNU make to not export all variables.
> # Otherwise a system limit (for SysV at least) may be exceeded.
> diff --git a/gold/testsuite/bsymbolic_non_weak_functions.c b/gold/testsuite/bsymbolic_non_weak_functions.c
> new file mode 100644
> index 00000000000..d2002696658
> --- /dev/null
> +++ b/gold/testsuite/bsymbolic_non_weak_functions.c
> @@ -0,0 +1,46 @@
> +// bsymbolic_non_weak_functions.cc -- Test -Bsymbolic-non-weak-functions
> +
> +// Copyright (C) 2021 Free Software Foundation, Inc.
> +
> +// This file is part of gold.
> +
> +// This program is free software; you can redistribute it and/or modify
> +// it under the terms of the GNU General Public License as published by
> +// the Free Software Foundation; either version 3 of the License, or
> +// (at your option) any later version.
> +
> +// This program is distributed in the hope that it will be useful,
> +// but WITHOUT ANY WARRANTY; without even the implied warranty of
> +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +// GNU General Public License for more details.
> +
> +// You should have received a copy of the GNU General Public License
> +// along with this program; if not, write to the Free Software
> +// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
> +// MA 02110-1301, USA.
> +
> +// The goal of this program is to verify that the --dynamic-list option
> +// allows overrides for symbols listed in the file, and does symbolic
> +// binding for symbols not listed.
> +
> +#include <stdint.h>
> +
> +int global_data = 0;
> +
> +__attribute__ ((noinline)) void global_fun (void);
> +void global_fun (void) { }
> +
> +__attribute__ ((weak, noinline)) void weak_fun (void);
> +void weak_fun (void) { }
> +
> +uintptr_t test (void);
> +
> +uintptr_t test (void)
> +{
> + uintptr_t x = global_data;
> + x += (uintptr_t)&global_fun;
> + x += (uintptr_t)&weak_fun;
> + global_fun ();
> + weak_fun ();
> + return x;
> +}
> diff --git a/gold/testsuite/bsymbolic_non_weak_functions.sh b/gold/testsuite/bsymbolic_non_weak_functions.sh
> new file mode 100755
> index 00000000000..b64d478a8d6
> --- /dev/null
> +++ b/gold/testsuite/bsymbolic_non_weak_functions.sh
> @@ -0,0 +1,46 @@
> +#!/bin/sh
> +
> +# bsymbolic_non_weak_functions.sh -- Test -Bsymbolic-non-weak-functions
> +
> +# Copyright (C) 2021 Free Software Foundation, Inc.
> +
> +# This file is part of gold.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +
> +# You should have received a copy of the GNU General Public License
> +# along with this program; if not, write to the Free Software
> +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
> +# MA 02110-1301, USA.
> +
> +check_present()
> +{
> + if ! grep -q "$1" bsymbolic_non_weak_functions.stdout
> + then
> + echo "Did not find $1"
> + exit 1
> + fi
> +}
> +
> +check_absent()
> +{
> + if grep -q "$1" bsymbolic_non_weak_functions.stdout
> + then
> + echo "Found unexpected $1"
> + exit 1
> + fi
> +}
> +
> +check_present 'GLOB_DAT.*global_data'
> +check_present 'GLOB_DAT.*weak_fun'
> +
> +check_present 'JUMP_SLOT.*weak_fun'
> +check_absent 'JUMP_SLOT.*global_fun'
> --
> 2.31.1.751.gd2f1c929bd-goog
>
Ping this and the GNU ld patch
https://sourceware.org/pipermail/binutils/2021-May/116703.html
This will be a great addition to the ELF world. (My libLLVM.so
libclang-cpp.so linked clang is more than 15% faster due to saved
dynamic relocations)
More information about the Binutils
mailing list