[ELF] Add -Bsymbolic-non-weak
This adds a new -Bsymbolic option that directly binds all non-weak symbols. There's a couple of reasons motivating this: * The new flag will match the default behavior on Mach-O, so you can get consistent behavior across platforms. * We have use cases for which making weak data preemptible is useful, but we don't want to pessimize access to non-weak data. (For a large internal app, we measured 2000+ data symbols whose accesses would be unnecessarily pessimized by `-Bsymbolic-functions`.) Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D158322
This commit is contained in:
@@ -53,8 +53,8 @@ enum ELFKind : uint8_t {
|
||||
};
|
||||
|
||||
// For -Bno-symbolic, -Bsymbolic-non-weak-functions, -Bsymbolic-functions,
|
||||
// -Bsymbolic.
|
||||
enum class BsymbolicKind { None, NonWeakFunctions, Functions, All };
|
||||
// -Bsymbolic-non-weak, -Bsymbolic.
|
||||
enum class BsymbolicKind { None, NonWeakFunctions, Functions, NonWeak, All };
|
||||
|
||||
// For --build-id.
|
||||
enum class BuildIdKind { None, Fast, Md5, Sha1, Hexstring, Uuid };
|
||||
|
||||
@@ -1155,13 +1155,15 @@ static void readConfigs(opt::InputArgList &args) {
|
||||
config->androidMemtagMode = getMemtagMode(args);
|
||||
config->auxiliaryList = args::getStrings(args, OPT_auxiliary);
|
||||
config->armBe8 = args.hasArg(OPT_be8);
|
||||
if (opt::Arg *arg =
|
||||
args.getLastArg(OPT_Bno_symbolic, OPT_Bsymbolic_non_weak_functions,
|
||||
OPT_Bsymbolic_functions, OPT_Bsymbolic)) {
|
||||
if (opt::Arg *arg = args.getLastArg(
|
||||
OPT_Bno_symbolic, OPT_Bsymbolic_non_weak_functions,
|
||||
OPT_Bsymbolic_functions, OPT_Bsymbolic_non_weak, OPT_Bsymbolic)) {
|
||||
if (arg->getOption().matches(OPT_Bsymbolic_non_weak_functions))
|
||||
config->bsymbolic = BsymbolicKind::NonWeakFunctions;
|
||||
else if (arg->getOption().matches(OPT_Bsymbolic_functions))
|
||||
config->bsymbolic = BsymbolicKind::Functions;
|
||||
else if (arg->getOption().matches(OPT_Bsymbolic_non_weak))
|
||||
config->bsymbolic = BsymbolicKind::NonWeak;
|
||||
else if (arg->getOption().matches(OPT_Bsymbolic))
|
||||
config->bsymbolic = BsymbolicKind::All;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,9 @@ def Bno_symbolic: F<"Bno-symbolic">, HelpText<"Don't bind default visibility def
|
||||
|
||||
def Bsymbolic: F<"Bsymbolic">, HelpText<"Bind default visibility defined symbols locally for -shared">;
|
||||
|
||||
def Bsymbolic_non_weak: F<"Bsymbolic-non-weak">,
|
||||
HelpText<"Bind default visibility defined STB_GLOBAL symbols locally for -shared">;
|
||||
|
||||
def Bsymbolic_functions: F<"Bsymbolic-functions">,
|
||||
HelpText<"Bind default visibility defined function symbols locally for -shared">;
|
||||
|
||||
|
||||
@@ -365,6 +365,8 @@ bool elf::computeIsPreemptible(const Symbol &sym) {
|
||||
// in the dynamic list. -Bsymbolic-non-weak-functions is a non-weak subset of
|
||||
// -Bsymbolic-functions.
|
||||
if (config->symbolic ||
|
||||
(config->bsymbolic == BsymbolicKind::NonWeak &&
|
||||
sym.binding != STB_WEAK) ||
|
||||
(config->bsymbolic == BsymbolicKind::Functions && sym.isFunc()) ||
|
||||
(config->bsymbolic == BsymbolicKind::NonWeakFunctions && sym.isFunc() &&
|
||||
sym.binding != STB_WEAK))
|
||||
|
||||
@@ -82,6 +82,9 @@ Bind default visibility defined symbols locally for
|
||||
Also set the
|
||||
.Dv DF_SYMBOLIC
|
||||
flag.
|
||||
.It Fl Bsymbolic-non-weak
|
||||
Bind default visibility defined STB_GLOBAL symbols locally for
|
||||
.Fl shared.
|
||||
.It Fl Bsymbolic-functions
|
||||
Bind default visibility defined function symbols locally for
|
||||
.Fl shared.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# RUN: llvm-readobj -r %t0.so | FileCheck %s --check-prefix=REL_DEF
|
||||
# RUN: llvm-objdump -d %t0.so | FileCheck %s --check-prefix=ASM_DEF
|
||||
|
||||
## -Bsymbolic-functions makes all STB_GLOBAL STT_FUNC definitions non-preemptible.
|
||||
## -Bsymbolic-non-weak-functions makes all STB_GLOBAL STT_FUNC definitions non-preemptible.
|
||||
# RUN: ld.lld -shared -Bsymbolic-non-weak-functions %t/a.o %t/b.o -o %t1.so
|
||||
# RUN: llvm-readobj -r %t1.so | FileCheck %s --check-prefix=REL_GFUN
|
||||
# RUN: llvm-objdump -d %t1.so | FileCheck %s --check-prefix=ASM_GFUN
|
||||
@@ -21,6 +21,11 @@
|
||||
# RUN: llvm-readobj -r %t3.so | FileCheck %s --check-prefix=REL_ALL
|
||||
# RUN: llvm-objdump -d %t3.so | FileCheck %s --check-prefix=ASM_ALL
|
||||
|
||||
## -Bsymbolic-non-weak makes all STB_GLOBAL definitions non-preemptible.
|
||||
# RUN: ld.lld -shared -Bsymbolic-non-weak %t/a.o %t/b.o -o %t4.so
|
||||
# RUN: llvm-readobj -r %t4.so | FileCheck %s --check-prefix=REL_GALL
|
||||
# RUN: llvm-objdump -d %t4.so | FileCheck %s --check-prefix=ASM_GALL
|
||||
|
||||
# RUN: ld.lld -shared -Bsymbolic-functions -Bsymbolic %t/a.o %t/b.o -o %t.so
|
||||
# RUN: cmp %t.so %t3.so
|
||||
# RUN: ld.lld -shared -Bsymbolic -Bsymbolic-functions %t/a.o %t/b.o -o %t.so
|
||||
@@ -37,6 +42,7 @@
|
||||
# REL_DEF: .rela.dyn {
|
||||
# REL_DEF-NEXT: R_X86_64_RELATIVE -
|
||||
# REL_DEF-NEXT: R_X86_64_RELATIVE -
|
||||
# REL_DEF-NEXT: R_X86_64_64 data_weak_default
|
||||
# REL_DEF-NEXT: R_X86_64_64 data_default
|
||||
# REL_DEF-NEXT: }
|
||||
# REL_DEF-NEXT: .rela.plt {
|
||||
@@ -59,6 +65,7 @@
|
||||
# REL_GFUN: .rela.dyn {
|
||||
# REL_GFUN-NEXT: R_X86_64_RELATIVE -
|
||||
# REL_GFUN-NEXT: R_X86_64_RELATIVE -
|
||||
# REL_GFUN-NEXT: R_X86_64_64 data_weak_default
|
||||
# REL_GFUN-NEXT: R_X86_64_64 data_default
|
||||
# REL_GFUN-NEXT: }
|
||||
# REL_GFUN-NEXT: .rela.plt {
|
||||
@@ -79,6 +86,7 @@
|
||||
# REL_FUN: .rela.dyn {
|
||||
# REL_FUN-NEXT: R_X86_64_RELATIVE -
|
||||
# REL_FUN-NEXT: R_X86_64_RELATIVE -
|
||||
# REL_FUN-NEXT: R_X86_64_64 data_weak_default
|
||||
# REL_FUN-NEXT: R_X86_64_64 data_default
|
||||
# REL_FUN-NEXT: }
|
||||
# REL_FUN-NEXT: .rela.plt {
|
||||
@@ -99,6 +107,7 @@
|
||||
# REL_ALL-NEXT: R_X86_64_RELATIVE -
|
||||
# REL_ALL-NEXT: R_X86_64_RELATIVE -
|
||||
# REL_ALL-NEXT: R_X86_64_RELATIVE -
|
||||
# REL_ALL-NEXT: R_X86_64_RELATIVE -
|
||||
# REL_ALL-NEXT: }
|
||||
# REL_ALL-NEXT: .rela.plt {
|
||||
# REL_ALL-NEXT: R_X86_64_JUMP_SLOT undef
|
||||
@@ -113,6 +122,26 @@
|
||||
# ASM_ALL-NEXT: callq {{.*}} <notype_default>
|
||||
# ASM_ALL-NEXT: callq {{.*}} <undef@plt>
|
||||
|
||||
# REL_GALL: .rela.dyn {
|
||||
# REL_GALL-NEXT: R_X86_64_RELATIVE -
|
||||
# REL_GALL-NEXT: R_X86_64_RELATIVE -
|
||||
# REL_GALL-NEXT: R_X86_64_RELATIVE -
|
||||
# REL_GALL-NEXT: R_X86_64_64 data_weak_default
|
||||
# REL_GALL-NEXT: }
|
||||
# REL_GALL-NEXT: .rela.plt {
|
||||
# REL_GALL-NEXT: R_X86_64_JUMP_SLOT weak_default
|
||||
# REL_GALL-NEXT: R_X86_64_JUMP_SLOT undef
|
||||
# REL_GALL-NEXT: }
|
||||
|
||||
# ASM_GALL: <_start>:
|
||||
# ASM_GALL-NEXT: callq {{.*}} <default>
|
||||
# ASM_GALL-NEXT: callq {{.*}} <protected>
|
||||
# ASM_GALL-NEXT: callq {{.*}} <hidden>
|
||||
# ASM_GALL-NEXT: callq {{.*}} <weak_default@plt>
|
||||
# ASM_GALL-NEXT: callq {{.*}} <ext_default>
|
||||
# ASM_GALL-NEXT: callq {{.*}} <notype_default>
|
||||
# ASM_GALL-NEXT: callq {{.*}} <undef@plt>
|
||||
|
||||
#--- a.s
|
||||
.globl default, protected, hidden, notype_default
|
||||
.weak weak_default
|
||||
@@ -144,16 +173,20 @@ _start:
|
||||
|
||||
.data
|
||||
.quad data_default
|
||||
.quad data_weak_default
|
||||
.quad data_protected
|
||||
.quad data_hidden
|
||||
|
||||
.globl data_default, data_protected, data_hidden
|
||||
.globl data_default, data_weak_default, data_protected, data_hidden
|
||||
.weak data_weak_default
|
||||
.protected data_protected
|
||||
.hidden data_hidden
|
||||
.type data_default, @object
|
||||
.type data_weak_default, @object
|
||||
.type data_protected, @object
|
||||
.type data_hidden, @object
|
||||
data_default: .byte 0
|
||||
data_weak_default: .byte 0
|
||||
data_protected: .byte 0
|
||||
data_hidden: .byte 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user