forked from OSchip/llvm-project
[ELF] - Implement filter library support (-F / --filter)
This is PR33766. -F name --filter=name When creating an ELF shared object, set the internal DT_FILTER field to the specified name. This tells the dynamic linker that the symbol table of the shared object which is being created should be used as a filter on the symbol table of the shared object name. If you later link a program against this filter object, then, when you run the program, the dynamic linker will see the DT_FILTER field. The dynamic linker will resolve symbols according to the symbol table of the filter object as usual, but it will actually link to the definitions found in the shared object name. Thus the filter object can be used to select a subset of the symbols provided by the object name. (https://linux.die.net/man/1/ld). Shared Objects as Filters: https://docs.oracle.com/cd/E19683-01/817-3677/chapter4-31738/index.html Differential revision: https://reviews.llvm.org/D35352 llvm-svn: 308167
This commit is contained in:
parent
7ac3efacc0
commit
f525c928cf
|
@ -99,6 +99,7 @@ struct Configuration {
|
||||||
std::vector<VersionDefinition> VersionDefinitions;
|
std::vector<VersionDefinition> VersionDefinitions;
|
||||||
std::vector<llvm::StringRef> Argv;
|
std::vector<llvm::StringRef> Argv;
|
||||||
std::vector<llvm::StringRef> AuxiliaryList;
|
std::vector<llvm::StringRef> AuxiliaryList;
|
||||||
|
std::vector<llvm::StringRef> FilterList;
|
||||||
std::vector<llvm::StringRef> SearchPaths;
|
std::vector<llvm::StringRef> SearchPaths;
|
||||||
std::vector<llvm::StringRef> SymbolOrderingFile;
|
std::vector<llvm::StringRef> SymbolOrderingFile;
|
||||||
std::vector<llvm::StringRef> Undefined;
|
std::vector<llvm::StringRef> Undefined;
|
||||||
|
|
|
@ -259,6 +259,9 @@ static void checkOptions(opt::InputArgList &Args) {
|
||||||
if (Config->Pie && Config->Shared)
|
if (Config->Pie && Config->Shared)
|
||||||
error("-shared and -pie may not be used together");
|
error("-shared and -pie may not be used together");
|
||||||
|
|
||||||
|
if (!Config->Shared && !Config->FilterList.empty())
|
||||||
|
error("-F may not be used without -shared");
|
||||||
|
|
||||||
if (!Config->Shared && !Config->AuxiliaryList.empty())
|
if (!Config->Shared && !Config->AuxiliaryList.empty())
|
||||||
error("-f may not be used without -shared");
|
error("-f may not be used without -shared");
|
||||||
|
|
||||||
|
@ -631,6 +634,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
|
||||||
getArg(Args, OPT_export_dynamic, OPT_no_export_dynamic, false);
|
getArg(Args, OPT_export_dynamic, OPT_no_export_dynamic, false);
|
||||||
Config->FatalWarnings =
|
Config->FatalWarnings =
|
||||||
getArg(Args, OPT_fatal_warnings, OPT_no_fatal_warnings, false);
|
getArg(Args, OPT_fatal_warnings, OPT_no_fatal_warnings, false);
|
||||||
|
Config->FilterList = getArgs(Args, OPT_filter);
|
||||||
Config->Fini = Args.getLastArgValue(OPT_fini, "_fini");
|
Config->Fini = Args.getLastArgValue(OPT_fini, "_fini");
|
||||||
Config->GcSections = getArg(Args, OPT_gc_sections, OPT_no_gc_sections, false);
|
Config->GcSections = getArg(Args, OPT_gc_sections, OPT_no_gc_sections, false);
|
||||||
Config->GdbIndex = Args.hasArg(OPT_gdb_index);
|
Config->GdbIndex = Args.hasArg(OPT_gdb_index);
|
||||||
|
|
|
@ -104,6 +104,8 @@ def export_dynamic_symbol: S<"export-dynamic-symbol">,
|
||||||
def fatal_warnings: F<"fatal-warnings">,
|
def fatal_warnings: F<"fatal-warnings">,
|
||||||
HelpText<"Treat warnings as errors">;
|
HelpText<"Treat warnings as errors">;
|
||||||
|
|
||||||
|
def filter: J<"filter=">, HelpText<"Set DT_FILTER field to the specified name">;
|
||||||
|
|
||||||
def fini: S<"fini">, MetaVarName<"<symbol>">,
|
def fini: S<"fini">, MetaVarName<"<symbol>">,
|
||||||
HelpText<"Specify a finalizer function">;
|
HelpText<"Specify a finalizer function">;
|
||||||
|
|
||||||
|
@ -305,6 +307,7 @@ def alias_exclude_libs: J<"exclude-libs=">, Alias<exclude_libs>;
|
||||||
def alias_export_dynamic_E: Flag<["-"], "E">, Alias<export_dynamic>;
|
def alias_export_dynamic_E: Flag<["-"], "E">, Alias<export_dynamic>;
|
||||||
def alias_export_dynamic_symbol: J<"export-dynamic-symbol=">,
|
def alias_export_dynamic_symbol: J<"export-dynamic-symbol=">,
|
||||||
Alias<export_dynamic_symbol>;
|
Alias<export_dynamic_symbol>;
|
||||||
|
def alias_filter: Separate<["-"], "F">, Alias<filter>;
|
||||||
def alias_fini_fini: J<"fini=">, Alias<fini>;
|
def alias_fini_fini: J<"fini=">, Alias<fini>;
|
||||||
def alias_format_b: S<"b">, Alias<format>;
|
def alias_format_b: S<"b">, Alias<format>;
|
||||||
def alias_hash_style_hash_style: J<"hash-style=">, Alias<hash_style>;
|
def alias_hash_style_hash_style: J<"hash-style=">, Alias<hash_style>;
|
||||||
|
|
|
@ -1024,6 +1024,8 @@ DynamicSection<ELFT>::DynamicSection()
|
||||||
template <class ELFT> void DynamicSection<ELFT>::addEntries() {
|
template <class ELFT> void DynamicSection<ELFT>::addEntries() {
|
||||||
// Add strings to .dynstr early so that .dynstr's size will be
|
// Add strings to .dynstr early so that .dynstr's size will be
|
||||||
// fixed early.
|
// fixed early.
|
||||||
|
for (StringRef S : Config->FilterList)
|
||||||
|
add({DT_FILTER, InX::DynStrTab->addString(S)});
|
||||||
for (StringRef S : Config->AuxiliaryList)
|
for (StringRef S : Config->AuxiliaryList)
|
||||||
add({DT_AUXILIARY, InX::DynStrTab->addString(S)});
|
add({DT_AUXILIARY, InX::DynStrTab->addString(S)});
|
||||||
if (!Config->Rpath.empty())
|
if (!Config->Rpath.empty())
|
||||||
|
|
|
@ -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 Filter library: [foo.so]
|
||||||
|
# CHECK-NEXT: 0x000000007FFFFFFF FILTER Filter library: [boo.so]
|
||||||
|
|
||||||
|
# RUN: not ld.lld %t.o -F x -o %t 2>&1 | FileCheck -check-prefix=ERR %s
|
||||||
|
# ERR: -F may not be used without -shared
|
Loading…
Reference in New Issue