Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -37,6 +37,7 @@ std::string RPath; std::vector InputSearchPaths; bool AllowMultipleDefinition; + bool Bsymbolic; bool DiscardAll; bool DiscardLocals; bool DiscardNone; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -163,6 +163,7 @@ setELFType(Arg->getValue()); Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition); + Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic); Config->DiscardAll = Args.hasArg(OPT_discard_all); Config->DiscardLocals = Args.hasArg(OPT_discard_locals); Config->DiscardNone = Args.hasArg(OPT_discard_none); Index: ELF/Options.td =================================================================== --- ELF/Options.td +++ ELF/Options.td @@ -1,5 +1,8 @@ include "llvm/Option/OptParser.td" +def Bsymbolic: Flag<["-"], "Bsymbolic">, + HelpText<"Bind defined symbols locally">; + def Bdynamic: Flag<["-"], "Bdynamic">, HelpText<"Link against shared libraries">; Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -333,8 +333,10 @@ ++NumEntries; // DT_INIT if (FiniSym) ++NumEntries; // DT_FINI - if (Config->ZNow) + if (Config->ZNow || Config->Bsymbolic) ++NumEntries; // DT_FLAGS_1 + if (Config->Bsymbolic) + ++NumEntries; // DT_SYMBOLIC ++NumEntries; // DT_NULL @@ -407,8 +409,17 @@ if (FiniSym) WritePtr(DT_FINI, getSymVA(*FiniSym)); + uint32_t Flags = 0; + if (Config->Bsymbolic) { + // For back-compatibility with old dynamic linkers. + WriteVal(DT_SYMBOLIC, 0); + + Flags |= DF_SYMBOLIC; + } if (Config->ZNow) - WriteVal(DT_FLAGS_1, DF_1_NOW); + Flags |= DF_1_NOW; + if (Flags) + WriteVal(DT_FLAGS_1, Flags); WriteVal(DT_NULL, 0); } Index: test/elf2/dt_flags.s =================================================================== --- test/elf2/dt_flags.s +++ test/elf2/dt_flags.s @@ -2,17 +2,19 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t # RUN: ld.lld2 -shared %t -o %t.so -# RUN: ld.lld2 -z now %t %t.so -o %t1 +# RUN: ld.lld2 -z now -Bsymbolic %t %t.so -o %t1 # RUN: ld.lld2 %t %t.so -o %t2 -# RUN: llvm-readobj -dynamic-table %t1 | FileCheck -check-prefix=NOW %s +# RUN: llvm-readobj -dynamic-table %t1 | FileCheck -check-prefix=FLAGS %s # RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s -# NOW: DynamicSection [ -# NOW: 0x000000006FFFFFFB FLAGS_1 NOW -# NOW: ] +# FLAGS: DynamicSection [ +# FLAGS: 0x0000000000000010 SYMBOLIC 0x0 +# FLAGS: 0x000000006FFFFFFB FLAGS_1 NOW GLOBAL +# FLAGS: ] # CHECK: DynamicSection [ -# CHECK-NOT: 0x000000006FFFFFFB FLAGS_1 NOW +# CHECK-NOT: 0x0000000000000010 SYMBOLIC 0x0 +# CHECK-NOT: 0x000000006FFFFFFB FLAGS_1 NOW GLOBAL # CHECK: ] .globl _start Index: test/elf2/now.s =================================================================== --- test/elf2/now.s +++ test/elf2/now.s @@ -1,19 +0,0 @@ -# REQUIRES: x86 - -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# RUN: ld.lld2 -shared %t -o %t.so -# RUN: ld.lld2 -z now %t %t.so -o %t1 -# RUN: ld.lld2 %t %t.so -o %t2 -# RUN: llvm-readobj -dynamic-table %t1 | FileCheck -check-prefix=NOW %s -# RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s - -# NOW: DynamicSection [ -# NOW: 0x000000006FFFFFFB FLAGS_1 NOW -# NOW: ] - -# CHECK: DynamicSection [ -# CHECK-NOT: 0x000000006FFFFFFB FLAGS_1 NOW -# CHECK: ] - -.globl _start -_start: