Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -73,6 +73,12 @@ uint8_t OriginalBinding; }; +// For -F/--filter and -F/--auxilary. +struct Filter { + bool IsAux; + llvm::StringRef Filtee; +}; + // This struct contains the global configuration for the linker. // Most fields are direct mapping from the command line options // and such fields have the same name as the corresponding options. @@ -97,8 +103,8 @@ llvm::StringRef ThinLTOCacheDir; std::string Rpath; std::vector VersionDefinitions; + std::vector FiltersList; std::vector Argv; - std::vector AuxiliaryList; std::vector SearchPaths; std::vector SymbolOrderingFile; std::vector Undefined; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -259,8 +259,8 @@ if (Config->Pie && Config->Shared) error("-shared and -pie may not be used together"); - if (!Config->Shared && !Config->AuxiliaryList.empty()) - error("-f may not be used without -shared"); + if (!Config->Shared && !Config->FiltersList.empty()) + error("-f/-F may not be used without -shared"); if (Config->Relocatable) { if (Config->Shared) @@ -610,10 +610,18 @@ return true; } +std::vector getFilters(opt::InputArgList &Args) { + std::vector Ret; + for (StringRef S : getArgs(Args, OPT_auxiliary)) + Ret.push_back({true, S}); + for (StringRef S : getArgs(Args, OPT_filter)) + Ret.push_back({false, S}); + return Ret; +} + // Initializes Config members by the command line options. void LinkerDriver::readConfigs(opt::InputArgList &Args) { Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition); - Config->AuxiliaryList = getArgs(Args, OPT_auxiliary); Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic); Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions); Config->CompressDebugSections = getCompressDebugSections(Args); @@ -631,6 +639,7 @@ getArg(Args, OPT_export_dynamic, OPT_no_export_dynamic, false); Config->FatalWarnings = getArg(Args, OPT_fatal_warnings, OPT_no_fatal_warnings, false); + Config->FiltersList = getFilters(Args); Config->Fini = Args.getLastArgValue(OPT_fini, "_fini"); Config->GcSections = getArg(Args, OPT_gc_sections, OPT_no_gc_sections, false); Config->GdbIndex = Args.hasArg(OPT_gdb_index); Index: ELF/Options.td =================================================================== --- ELF/Options.td +++ ELF/Options.td @@ -104,6 +104,8 @@ def fatal_warnings: F<"fatal-warnings">, HelpText<"Treat warnings as errors">; +def filter: J<"filter=">, HelpText<"Set DT_FILTER field to the specified name">; + def fini: S<"fini">, MetaVarName<"">, HelpText<"Specify a finalizer function">; @@ -305,6 +307,7 @@ def alias_export_dynamic_E: Flag<["-"], "E">, Alias; def alias_export_dynamic_symbol: J<"export-dynamic-symbol=">, Alias; +def alias_filter: Separate<["-"], "F">, Alias; def alias_fini_fini: J<"fini=">, Alias; def alias_format_b: S<"b">, Alias; def alias_hash_style_hash_style: J<"hash-style=">, Alias; Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -1019,8 +1019,9 @@ template void DynamicSection::addEntries() { // Add strings to .dynstr early so that .dynstr's size will be // fixed early. - for (StringRef S : Config->AuxiliaryList) - add({DT_AUXILIARY, InX::DynStrTab->addString(S)}); + for (Filter F : Config->FiltersList) + add({F.IsAux ? DT_AUXILIARY : DT_FILTER, + InX::DynStrTab->addString(F.Filtee)}); if (!Config->Rpath.empty()) add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH, InX::DynStrTab->addString(Config->Rpath)}); Index: test/ELF/auxiliary.s =================================================================== --- test/ELF/auxiliary.s +++ test/ELF/auxiliary.s @@ -4,9 +4,9 @@ # CHECK: DynamicSection [ # CHECK-NEXT: Tag Type Name/Value -# CHECK-NEXT: 0x000000007FFFFFFD AUXILIARY Auxiliary library: [aaa] -# CHECK-NEXT: 0x000000007FFFFFFD AUXILIARY Auxiliary library: [bbb] +# CHECK-NEXT: 0x000000007FFFFFFD AUXILIARY AuxiliaryLibrary (aaa) +# CHECK-NEXT: 0x000000007FFFFFFD AUXILIARY AuxiliaryLibrary (bbb) # RUN: not ld.lld %t.o -f aaa --auxiliary bbb -o %t 2>&1 \ # RUN: | FileCheck -check-prefix=ERR %s -# ERR: -f may not be used without -shared +# ERR: -f/-F may not be used without -shared Index: test/ELF/filter.s =================================================================== --- test/ELF/filter.s +++ test/ELF/filter.s @@ -0,0 +1,15 @@ +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld %t.o -shared -F foo.so -F boo.so -o %t1 +# RUN: llvm-readobj --dynamic-table %t1 | FileCheck %s + +# Test alias. +# RUN: ld.lld %t.o -shared --filter=foo.so --filter=boo.so -o %t2 +# RUN: llvm-readobj --dynamic-table %t2 | FileCheck %s + +# CHECK: DynamicSection [ +# CHECK-NEXT: Tag Type Name/Value +# CHECK-NEXT: 0x000000007FFFFFFF FILTER FilterLibrary (foo.so) +# CHECK-NEXT: 0x000000007FFFFFFF FILTER FilterLibrary (boo.so) + +# RUN: not ld.lld %t.o -F x -o %t 2>&1 | FileCheck -check-prefix=ERR %s +# ERR: -f/-F may not be used without -shared