diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -53,8 +53,8 @@ }; // 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 }; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1155,13 +1155,15 @@ 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; } diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -42,6 +42,9 @@ 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">; diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -365,6 +365,8 @@ // 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)) diff --git a/lld/docs/ld.lld.1 b/lld/docs/ld.lld.1 --- a/lld/docs/ld.lld.1 +++ b/lld/docs/ld.lld.1 @@ -82,6 +82,9 @@ 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. diff --git a/lld/test/ELF/bsymbolic.s b/lld/test/ELF/bsymbolic.s --- a/lld/test/ELF/bsymbolic.s +++ b/lld/test/ELF/bsymbolic.s @@ -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 {{.*}} # ASM_ALL-NEXT: callq {{.*}} +# 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 {{.*}} +# ASM_GALL-NEXT: callq {{.*}} +# ASM_GALL-NEXT: callq {{.*}} +# ASM_GALL-NEXT: callq {{.*}} +# ASM_GALL-NEXT: callq {{.*}} +# ASM_GALL-NEXT: callq {{.*}} +# ASM_GALL-NEXT: callq {{.*}} + #--- a.s .globl default, protected, hidden, notype_default .weak weak_default @@ -144,16 +173,20 @@ .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