[PATCH] gold: Add -Bsymbolic-non-weak-functions
Fangrui Song
maskray@google.com
Thu May 20 06:05:02 GMT 2021
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
More information about the Binutils
mailing list